2013-03-26 42 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

相关问题