2017-05-31 36 views
0

イムは、COMポートから読み取ろうと、これは私のコードですはBaseStream.BeginReadとCOMポートからの読み取りと、サブストリングを取得

Rで始まり、13を持っている文字列をある何イム取得しようとして
public string HouseState() 
    { 
     string state = string.Empty; 
    if (!Variables.portBusy) 
      { 
       // Begin communications 
       var blockLimit = 13; 
       openSerial(); 
       byte[] buffer = new byte[blockLimit]; 
       Action kickoffRead = null; 

       kickoffRead = delegate 
       { 
        serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) 
        { 
         try 
         { 
          int actualLength = serialPort.BaseStream.EndRead(ar); 
          byte[] received = new byte[actualLength]; 
          Buffer.BlockCopy(buffer, 0, received, 0, actualLength); 
          state += System.Text.Encoding.UTF8.GetString(received); 
          //MessageBox.Show(state); 
         } 
         catch (IOException exc) 
         { 
          //handleAppSerialError(exc); 
         } 
         if (state.Count() <= 13) 
          kickoffRead(); 
        }, null); 
       }; 
       kickoffRead(); 
      } 
     MessageBox.Show(state); 
     var index = state.IndexOf("R"); 
     var command = string.Empty; 
     if (index >= 0) 
      command = state.Substring(index, 13); 


     return command; 
    } 

文字。時々ポートが半分の文字列を送信しますので、私はこれを行う:場合(state.Count()< = 13)

しかし BaseStream内の状態の文字列は、私は状態の文字列を読み込むしようとしたとき、私は、欲しいものを取得しながら、それは空に見えます。 MessageBoxは空の文字列を表示します。

なぜこれが起こっていますか?実際の読み込みがまだ完了していないこととstateはまだ空であるあなたがMessageBox.Show(state);に取得している瞬間によるよう

答えて

2

SerialPort.BaseStreamBeginRead方法は非同期です。あなたは必要なすべてのデータが読み込まれるまで待つ必要があります。

// ..................... 
var readComplete = new ManualResetEvent(false); 
kickoffRead = delegate 
{ 
    serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) 
    { 
     // ................... 
     if (state.Count() <= 13) 
      kickoffRead(); 
     else 
      readComplete.Set(); 
    }, null); 
}; 
kickoffRead(); 
readComplete.WaitOne(); 
// ...................... 

BeginRead/EndReadベースの非同期読み取りがReadAsync 1に取って代わられていると述べました。オリジナルのスニペットに基づいても、同期読み取りでも問題はありません。あなたはこの質問への答えの両方の例を見つけるかもしれません:C# Async Serial Port Read

+0

あなたはロックブロー、私はそれが非同期であったことを知っていなかった、それはなぜ非同期コマンドが必要ですか? また、私はこのManualResetEventについて知りませんでした。 – CDrosos

+0

'async'キーワードは、[new async model](https://msdn.microsoft.com/library/hh191443(vs.110).aspx)メソッドで使用されるはずです。 。古い非同期モデル実装のため、 'BeginRead'はタスクと' async'/'await'を認識しません。 –

関連する問題