2012-04-08 24 views
0

なぜアプリはまだ閉じているのですか?
私はそれがシリアルポートからのデータの読み込みによって引き起こされると思います。

ComboBoxからシリアルポート番号を選択します。
機能シリアルポートからのデータに応じて、WriteDataアップデートのチェックボックスをオンにします。ここ
はエキスです:アプリが終了しない

// 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イベントが期待どおりに実行されていることを確認できますか(デバッガ/ロガー)? –

+1

'serialPort'オブジェクトが使い捨てであり(' SerialPort'がそうだと思いますが)、このコードで正しく処分していない可能性があります。変数のスコープがより制御され、 'using'ブロックでラップすることができるように、変数を再構成することができます。 – David

+0

@Henk Holterman - 他のスレッドはありません。私はシリアルポートからデータを読み始めるときにのみ、アプリケーションが正常に閉じて、それは正しく閉じられていません。 –

答えて

3

あなたのコードでは、クローズ()の呼び出しでプログラムをブロックし、デッドロックを引き起こす可能性が非常に高いです。問題のステートメントはDispatcher.Invoke()呼び出しです。その呼び出しは、UIスレッドが呼び出しを送出するまで完了できません。デッドロックは、Close()を呼び出すと同時にDataReceivedイベントが実行中であるときに発生します。イベントが実行されているため、Close()呼び出しを完了できません。 UIスレッドがアイドル状態ではないため、Invoke()が完了できないため、イベントハンドラが完了できません。イベントハンドラはClose()呼び出しでスタックされています。デッドロック市。

これはバグがあるため、特にのコードで発生する可能性があります。 DataReceivedでDiscardInBuffer()を呼び出します。これにより、受信したデータが破棄され、次のReadChar()呼び出しがブロックされ、受信したデータがもう待っています。

DiscardInBuffer()呼び出しを削除し、代わりにDispatcher.BeginInvoke()を使用してこの問題を解決します。

関連する問題