2012-04-08 139 views
0

为什么当我关闭它时,应用程序仍在工作。
我想这是由读取串口数据引起的。

串口号从ComboBox中选择。
功能写入数据更新复选框取决于来自串行端口的数据。
下面是摘录:应用程序不会退出

// Choosing of communication port from ComboBox 
    private void comboBoxCommunication_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (serialPort.IsOpen) 
     { 
      serialPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(Recieve); 
      serialPort.Close(); 
     } 
     try 
     { 
      ComboBoxItem cbi = (ComboBoxItem)comboBoxKomunikacia.SelectedItem; 
      portCommunication = cbi.Content.ToString(); 
      serialPort.PortName = portCommunication; 
      serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recieve); 
      serialPort.BaudRate = 2400; 
      serialPort.Open(); 
      serialPort.DiscardInBuffer(); 
     } 
     catch (IOException ex) 
     { 
      MessageBox.Show(ex.ToString(), "Error!", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 

    // Close the window 
    private void Window_Closed(object sender, EventArgs e) 
    { 
     if (serialPort.IsOpen) 
     {     
      serialPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(Recieve);     
      serialPort.Close(); 
     } 
    } 

    // Data reading 
    private delegate void UpdateUiTextDelegate(char text); 
    private void Recieve(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
    { 
     if (serialPort.IsOpen) 
     { 
      try 
      { 
       serialPort.DiscardInBuffer(); 
       char c = (char)serialPort.ReadChar(); 
       Dispatcher.Invoke(DispatcherPriority.Send, 
        new UpdateUiTextDelegate(WriteData), c);      
      } 
      catch(IOException ex) 
      { 
       MessageBox.Show(ex.ToString(), "Error!", MessageBoxButton.OK, MessageBoxImage.Error); 
      } 
     } 
    } 

    // Update of checkboxes 
    private void WriteData(char c) { ... } 
+0

任何其他线程?您能否验证(调试器/记录器)Closed事件是否按预期执行? – 2012-04-08 11:12:43

+1

如果'serialPort'对象是一次性的(我认为'SerialPort'是),那么在这段代码中没有正确地处理它是很有可能的。您可能需要重新构造它,以便变量的范围受到更多控制,并且可以封装在“使用”块中。 – David 2012-04-08 11:14:19

+0

@亨克霍尔特曼 - 没有其他线程。应用程序正常关闭,只有当我开始从串口读取数据时,它没有正确关闭。 – 2012-04-08 11:22:14

回答

3

你的代码是很容易造成僵局,在关闭()调用阻止程序。问题陈述是Dispatcher.Invoke()调用。直到UI线程发出呼叫,该呼叫才能完成。当您调用Close()并且DataReceived事件正在执行的同时发生死锁。由于事件正在运行,Close()调用无法完成。事件处理程序无法完成,因为Invoke()无法完成,因为UI线程不是空闲的,所以它停留在Close()调用中。僵局城市。

这是特别是可能发生在您的代码中,因为它有一个错误。你可以在DataReceived中调用DiscardInBuffer()。这抛弃了接收到的数据,所以下一次ReadChar()调用将会阻塞一段时间,等待更多的数据被接收,如果设备不再发送任何东西,则可能永远不会发送。

通过删除DiscardInBuffer()调用并使用Dispatcher.BeginInvoke()来解决此问题。