2009-11-08 2 views
6

У меня есть приложение, в котором я читаю из последовательного порта, все идет хорошо, пока я не закрою приложение. Когда я нажимаю [X], приложение просто зависает, пользовательский интерфейс: не отвечает.C#: Правильный способ закрыть SerialPort с Winforms

Я читал из порта в обработчик событий DataReceived, и я закрыть порт, когда FormClosed происходит:

private void MainForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     mySerialPort.Close(); 
    } 

ответ

6

Serial Port hangs while closing

Это известная проблема с классом SerialPort и описаны в этом Product Feedback статьи, а также несколько тем на этих форумах. Вы можете заметить увольнение «закрыто по дизайну».

+1

+1, это вяжется с предыдущим вопросом, что ОП в. Но для хорошего ответа SO вы могли бы опубликовать короткое резюме ** здесь **. Предположим, что эта страница движется? –

+2

НЕВЕРОЯТНО !!! это известная ошибка в рамках, которая закрыта MS как «работает так, как было разработано !!!» +1 для справки – mfeingold

+0

LOL. См. Мой ответ ниже. В .NET Framework существует серьезная ошибка кода последовательного порта, но это * NOT * it. –

9

Это не ошибка.

Единственная причина, по которой она зависает, когда вы ее закрываете, - это то, что в обработчике событий вашего объекта SerialPort вы синхронизируете вызов с основным потоком (обычно вызывающим вызовом). Метод close SerialPort ожидает поток EventLoopRunner, который прерывает события DataReceived/Error/PinChanged, но поскольку ваш собственный код в событии также ожидает ответа основного потока, вы сталкиваетесь с ситуацией с мертвой блокировкой.

Причина, по которой отчет об ошибке был закрыт «как запроектирован», объясняется тем, что «ошибка» находится в вашем собственном коде.

+5

Yup, используйте BeginInvoke, а не Invoke. –

+0

Спасибо, ребята, это правда ... BeginInvoke решил мою проблему. – pm89

1

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

+0

Он будет висеть на распоряжении также ... когда утилита закрывает его так, что вам придется использовать BeginInvoke. Конечно, неважно, закрываете ли вы приложение. Однако имеет значение, если вы открываете и закрываете несколько последовательных портов, не закрывая приложение. – cb88

5

Если ваше приложение вызывает Invoke для обработки полученных данных, попробуйте вместо этого вызвать BeginInvoke.

Вместо:

this.Invoke(d, new object[] { s, tb }); 

использование:

this.BeginInvoke(d, new object[] { s, tb }); 
Смежные вопросы