2012-04-12 13 views
0

まあ、私はこのSerialPortコントロールを使って最後の4日間struglingしてきましたが、満足のいく結果は得られませんでした。シリアルポート非同期読み取り(非ブロッキング)+スレッド

スケール(シンプルなリクエスト/レスポンスパターン)をシミュレートするac#progとcomunicatesするデバイス(Arduino UNO Board)があり、デバイスは3バイトからなるコマンドシーケンスを送信します):CHR(27)+ P + CHR(13)のでシミュレータはシミュレートされたウェイトで応答します(デバイスがキャッチしてどのようにこのウェイトを解析するので、これは問題ではありません)。 DataReceiveイベントを使用すると、Serialport.Read()を使用してデータが失われているようですので、これまでこの方法を無駄にしていました。 シミュレータは常に前記seqを聞いていなければなりません。のバイト数とGUIを持っている必要があります。私はこのために、GUIがロックされているのを防ぐためにスレッドを使用する必要があることを理解しています(おそらく背景作業者ですか?)と、この2つのスレッド間で(今)共有されているスレッドの並行/ (これは良いアプローチか、私の仮定が間違っているか、theresがこれを解決するより簡単な方法であるかどうかわからないので、私はこれについて助けを求めます)アドバイスと(たくさんの運がある)コード断片を求めているのか、それとも同じようなアプリを開発して解決したのか分かりません。

もっと詳しく説明する必要がある場合は、これまでに行ったコードを提供することができます。あなたはこれについて光を当てることができることを願っています。

ありがとうございます。

UPDATE 1


これは私がこれまで持っているコードです:コマンドが文字13(ASCIIでCR)で終了しなければならないので、だから、

ConcurrentQueue<byte> queue = new ConcurrentQueue<byte>(); 
.... 
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    bool listening = true; 
    while(listening) 
    { 
    if(serialPort.BytesToRead > 0) 
    { 
     byte b = (byte)serialPort.ReadByte(); 
     queue.Enqueue(b); 
    } 
    } 
} 

public string GetCommand() 
{ 
    string ret = ""; 
    byte[] ba = new byte[1]; 
    byte b = (byte)' '; 

    while(b!=13) 
    { 
     if(queue.TryDequeue(out b)) 
     { 
      ba[0] = b; 
      ret += ASCIIEncoding.ASCII.GetString([ba]); 
     } 
    } 
    return ret; 
} 

このGetCommand()メソッドをテストするには、buton_clickイベント内のメインuiスレッドから呼び出すが、アプリケーションをハングするGetCommand()を呼び出す別のスレッドを作成する必要がありますか?

+0

私の質問が更新されました。私はhitechriderを試してみましたが、もう一度立ち往生しました。スレッディングはかなり複雑なテーマです。 – favner85

答えて

1

送信側の実装方法については、this answerを参照してください。

読み取り側では、専用スレッドを使用し、そのスレッドでポートからメッセージを読み込み、適切な並行データ構造(たとえば、ConcurrentQueue)でキューに入れ、すぐにループバックしてシリアルからの次の入力を待ちますポート。

キューからの入力を別のスレッドで消費します。

もっと効率的な方法があるかもしれませんが、この方法は実装が簡単で絶対的です。

2

これは、少量のデータに対しては問題ありません。しかし、http情報を渡すようなデータが大きければ、キューのサイズは十分ではないかもしれません。だから私はあなたがノンブロッキング型のアーキテクチャを使うべきだと思います。

関連する問題