2012-04-08 110 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()來解決此問題。