2013-03-26 90 views
0

我有一個關於爲什麼我的C#接口在串行端口連接期間凍結的問題。如果我連接到有效的串行端口(我的設備發送了我期望的字節數),則該接口不會凍結。但是,如果用戶嘗試連接到計算機上的另一個端口或我的設備的錯誤模型,那麼程序在發送'?'時不會返回任何數據。字符等等第一行:message [i] =(byte)port.BaseStream.ReadByte();導致超時並落入我的catch並嘗試連接3次,然後警告用戶連接失敗。在三次嘗試完成後,用戶界面工作正常,但在進行用戶界面時無法響應。有任何想法嗎?在此先感謝,下面是我的代碼。串行端口嘗試連接時C#UI凍結

public void windowLoop(object sender, EventArgs e) 
    { 
     if (Global.connecting) 
     { 
      try 
      { 
       if (i == 0) { port.BaseStream.Flush(); port.BaseStream.WriteByte(63); } 
       message[i] = (byte)port.BaseStream.ReadByte(); 
       if (i == 6) 
       { 
        connectAttempts = 1; 
        i = 0; 
        String result = Encoding.ASCII.GetString(message); 
        if (result == "ASUTTON") 
        { 
         //connection succeeded 
         Global.connecting = false; 
         Global.receiving = true; 
         setDisplay(2); 
        } 
        else 
        { 
         //connection failed 
         Global.connecting = false; 
         disconnect(); 
         MessageBox.Show(radio, "You are not connection to an Agent (Radio Version)", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information); 
        } 
       } 
       else 
       { 
        i++; 
       } 
      } 
      catch 
      { 
       if (connectAttempts >= connectAttemptsLimit) 
       { 
        connectAttempts = 1; 
        Global.connecting = false; 
        disconnect(); 
        MessageBox.Show(radio, "Your device failed to connect to the program.", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information); 
       } 
       else 
       { 
        connectAttempts++; 
       } 
      } 
     } 
     else if (Global.sending) 
     { 

以上是我通過DispatcherTimer對象連續運行的代碼,每隔10 ms運行一次。

回答

1

您可以使用Thread或者您可以使用Task TPL。還有一些事件可以在SerialPort類上使用,如DataReceived

如何將它從Read更改爲BeginRead。你可以使用AsyncCallback

byte[] received = new byte[port.BytesToRead]; 
result = port.BaseStream.BeginRead(received 
      , 0, port.BytesToRead, new AsyncCallback(ReadCallBack), port.BaseStream); 


private void ReadCallBack(IAsyncResult ar) 
    {    
     Stream stream = (Stream)ar.AsyncState; 

     // Do reading here? 
    } 
2

爲了保持應用程序響應,建議使用線程。與串口的通信是阻塞呼叫,並且在它可以確定該端口不工作之前它會等待超時。

理想的解決方案是使用後臺工作組件,並讓它嘗試連接到串行端口。

1

您可以嘗試通過串行端口將通信移至單獨的線程,或設置較低的超時。

1

DispatcherTimer根據MSDN是:

集成到分派器隊列是 在指定的時間間隔,並在指定的優先級處理的定時器。

這意味着它在Dispatcher pupm消息的同一線程上運行。所以在你的定時器請求的過程中,它會停止執行或處理隊列中的其他東西。

要解決此問題,請使用連接到System.Timers.Timer類事件中的serail端口的代碼,該代碼在分離線程上運行,因此在其執行期間不會阻塞UI

相關問題