2012-04-08 25 views
0

Warum App funktioniert immer noch, wenn ich es schließe.
Ich denke, es wird durch das Lesen von Daten von der seriellen Schnittstelle verursacht.

Die Nummer des seriellen Ports wird aus der ComboBox ausgewählt.
Funktion WriteData Update-Kontrollkästchen abhängig von Daten von der seriellen Schnittstelle.
Hier Extrakt:App wird nicht beendet

// 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

Irgendwelche anderen Themen? Können Sie überprüfen (Debugger/Logger), dass das Closed-Ereignis wie erwartet ausgeführt wird? –

+1

Wenn das 'serialPort' Objekt wegwerfbar ist (und ich denke,' SerialPort' ist), dann besteht eine gute Chance, dass Sie es in diesem Code nicht richtig entsorgen. Möglicherweise möchten Sie es neu strukturieren, damit der Gültigkeitsbereich der Variablen besser kontrolliert wird und in einen 'using'-Block gehüllt werden kann. – David

+0

@Henk Holterman - keine anderen Themen. App ist normal geschlossen, nur wenn ich Daten von der seriellen Schnittstelle lesen, ist es nicht richtig geschlossen. –

Antwort

3

Der Code ist sehr wahrscheinlich, Deadlock zu verursachen, das Programm auf der Close() Anrufblockierung. Die Problembeschreibung ist der Dispatcher.Invoke() -Aufruf. Dieser Anruf kann erst abgeschlossen werden, nachdem der Benutzer den Anruf gesendet hat. Der Deadlock tritt auf, wenn Sie Close() aufrufen und gleichzeitig das DataReceived-Ereignis ausgeführt wird. Der Aufruf von Close() kann nicht abgeschlossen werden, da das Ereignis ausgeführt wird. Der Ereignishandler kann nicht abgeschlossen werden, da Invoke() nicht abgeschlossen werden kann, da der UI-Thread nicht inaktiv ist und daher beim Aufruf von Close() hängen bleibt. Deadlock-Stadt.

Dies ist vor allem wahrscheinlich in Ihrem Code passieren, weil es einen Fehler hat. Sie rufen DiscardInBuffer() in DataReceived auf. Dadurch werden die empfangenen Daten weggeworfen, so dass der nächste ReadChar() - Aufruf eine Weile blockiert und darauf wartet, dass weitere Daten empfangen werden, möglicherweise für immer, wenn das Gerät nichts mehr sendet.

Beheben Sie dieses Problem, indem Sie den Aufruf DiscardInBuffer() löschen und stattdessen Dispatcher.BeginInvoke() verwenden.

Verwandte Themen