2017-05-31 156 views
0

我試着從COM端口讀取,這是我的代碼從BaseStream.BeginRead COM端口讀取並得到一個子

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; 
    } 

什麼即時試圖得到的是有R開始,有13個字符串字符。因爲有時端口發送一半的字符串我這樣做:如果(state.Count()< = 13)

不過,雖然裏面BaseStream狀態字符串得到我想要的東西,當我嘗試讀取狀態的字符串,它看起來是空的。 MessageBox顯示一個空字符串。

爲什麼會發生這種情況?

回答

2

SerialPort.BaseStreamBeginRead方法是異步所以,當你正在向MessageBox.Show(state);當下實際的讀取可能尚未完成,state仍然是空的。您需要等到所有必要的數據被讀取:

// ..................... 
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一個取代。並根據您的原始片段甚至同步閱讀是可以接受的在你的情況。你可以在這個問題的答案中找到兩個例子:C# Async Serial Port Read

+0

你搖滾兄弟,我不知道它是異步的,爲什麼它doens需要異步命令? 此外,我不知道這個ManualResetEvent,謝謝 – CDrosos

+0

'async'關鍵字應該與[新的異步模型](https://msdn.microsoft.com/library/hh191443(vs.110).aspx)方法一起使用。作爲舊的異步模型實現,'BeginRead'不知道任務和'async' /'await'。 –