2012-04-08 7 views
0

Почему приложение все еще работает, когда я его закрываю.
Я предполагаю, что это вызвано чтением данных из последовательного порта.

Номер последовательного порта выбирается из ComboBox.
Флажок функции WriteData update в зависимости от данных из последовательного порта.
Вот выдержка:Приложение не выходит

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

Любые другие темы? Можете ли вы проверить (отладчик/регистратор), что закрытое событие выполняется, как ожидалось? –

+1

Если объект 'serialPort' является одноразовым (и я думаю, что' SerialPort'), тогда есть справедливый шанс, что вы не распоряжаетесь им в этом коде. Вы можете захотеть переструктурировать его так, чтобы область действия переменной была более контролируемой и могла быть обернута в блок 'using'. – David

+0

@ Хенк Холтерман - нет других тем. Приложение закрыто нормально, только когда я начинаю считывать данные из последовательного порта, он не закрывается должным образом. –

ответ

3

Ваш код очень вероятно, вызовет затор, блокируя вашу программу Close() вызова. Оператор проблемы - вызов Dispatcher.Invoke(). Этот вызов не может завершиться до тех пор, пока поток пользовательского интерфейса не отправит вызов. Тупик возникает, когда вы вызываете Close(), и в то же время событие DataReceived занято. Вызов Close() не может быть завершен, так как событие запущено. Обработчик события не может завершить, потому что Invoke() не может завершить, потому что поток пользовательского интерфейса не простаивает, он застревает в вызове Close(). Тупиковый город.

Это особенно, вероятно, произойдет в вашем коде, потому что у него есть ошибка. Вы вызываете DiscardInBuffer() в DataReceived. Это отбрасывает полученные данные, поэтому следующий вызов ReadChar() будет блокироваться некоторое время, ожидая получения некоторых данных, возможно, навсегда, если устройство больше ничего не отправляет.

Устранить эту проблему, удалив вызов DiscardInBuffer() и используя Dispatcher.BeginInvoke().

Смежные вопросы