2015-03-17 3 views
1

Я думаю, что у меня проблема, когда я закрываю окно WPF, когда SerialPort открыт (я думаю, он все еще получает некоторые данные). Какой был бы лучший способ закрыть его? Пока я нашел решение, но не уверен, что его работа.Сделать SerialPort закрыть и остановить чтение данных при закрытии окна

Мои настройки SerialPort:

    serialPort.ReadTimeout = 1000; 
        serialPort = new SerialPort(); 
        serialPort.PortName = Application.Current.Properties["DevPort"].ToString(); 
        serialPort.BaudRate = 9600; 
        serialPort.StopBits = StopBits.One; 
        serialPort.DataBits = 8; 
        serialPort.Parity = Parity.None; 
        serialPort.Handshake = Handshake.None; 
        serialPort.DataReceived += serial_sp_DataReceived; 
        serialPort.Open(); 

метод Window.Closing:

if (serialPort.IsOpen) 
     { 
      this.Closing -= Window_Closing; 
      Thread CloseDown = new Thread(new ThreadStart(serialPort.Dispose)); 
      CloseDown.Start(); 
     } 

Трудно достичь этого окна заморозить (обычно это СЛУЧИЛОСЬ 1x/10h или более). Что было бы лучшим способом закрыть/удалить serialPort до закрытия окна?

@EDIT:

data_received метод:

int count = serialPort.BytesToRead; 
       byte[] ByteArray = new byte[count]; 
       serialPort.Read(ByteArray, 0, count); 
       ByteArray = SubArray(ByteArray, 5, 5); 

       string s2 = BitConverter.ToString(ByteArray); 

       String[] tempAry = s2.Split('-'); 
       byte[] decBytes2 = new byte[tempAry.Length]; 
       for (int i = 0; i < tempAry.Length; i++) 
        decBytes2[i] = Convert.ToByte(tempAry[i], 16); 

       string host; 
       int port = int.Parse(Application.Current.Properties["Port"].ToString()); 
       host = Application.Current.Properties["Host"].ToString(); 
       tekst = s2.Replace("-", ""); 
       string result = StartClient(host, port, tekst); 

       string[] _result = result.Split('_'); 
       tekst = ""; 
       if (_result[1].ToString() == "-1") 
       { 
        var thread = new Thread(new ThreadStart(ShowError)); 

        thread.SetApartmentState(ApartmentState.STA); 
        thread.Start(); 
        thread.Join(); 
        tekst = ""; 
        return; 
       } 
       card = _result[0]; 
       points = decimal.Parse(_result[1]); 

       thread1 = new Thread(() => pressButton(CardButton)); 

       thread1.SetApartmentState(ApartmentState.STA); 
       thread1.Start(); 
       thread1.Join(); 


ShowError method just shows my custom error window. PressButton method raises b.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); 
+1

Мой психический отладчик говорит, что вы используете Invoke() в обработчике событий DataReceived. Это очень сложно вызвать тупик, когда вы пытаетесь закрыть последовательный порт во время приема данных. Вместо этого используйте BeginInvoke(). –

+0

Я отредактировал и опубликовал свой метод dataReceived. – user13657

+0

Почему вы имеете дело с потоками и графикой? Это очень похоже на стрельбу по ногам ... подумайте о том, чтобы использовать async/wait, если вы можете –

ответ

0

Ваша проблема довольно родовая: как закрыть приложение, когда есть некоторые темы, все еще работают? Ответ довольно очевиден: попросите потоки закрыть и подождите, пока они действительно закончатся.

Однако ваша конкретная проблема может быть связана с тем, как обрабатывается SerialPort. Это связано с тем, что он использует базовый поток, и вы должны позаботиться о его максимально кратчайшем (то есть избегать любого блока).

Типичный случай, когда вы используете метод чтения, который блокирует поток, пока все необходимые данные не считывается: https://msdn.microsoft.com/en-us/library/ms143549(v=vs.110).aspx

Вместо этого, вы должны использовать другой подход: первый выглядывать, сколько байт уже получены, затем прочитайте их и больше ничего. Общий поток должен быть собран код: https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.bytestoread(v=vs.110).aspx

Посмотрите на пример моего здесь, старый, но все еще хорошо: http://cetdevelop.codeplex.com/SourceControl/latest#V2/Cet/IO/Cet.IO.Serial/SerialPortClient.cs

0

Вы должны рассмотреть утилизации экземпляра последовательного порта, как только считывание данных завершена , В данных, которые вы получаете, обратите внимание на отметку «Конец потока». Когда вы получите это, удалите последовательный порт.

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