Проблема SerialPort.Close () - не удается закрыть приложение с помощью диспетчера задач! - PullRequest
6 голосов
/ 19 августа 2010

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

Если устройство выходит из строя, ИНОГДА используется SerialPort.Close () - метод НИКОГДА не возвращается, и это действительно остановка показа.

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

Подключенное устройство представляет собой POS-принтер (USB), который имитирует COM3, это Epson TM-T88IV (очень хорошая модель, кстати).

Кто-нибудь из вас имеет опыт работы счто?

Ответы [ 6 ]

11 голосов
/ 19 августа 2010

Повторное открытие и закрытие порта не рекомендуется.Проверьте раздел «Примечания» в статье библиотеки MSDN для SerialPort.Close ().Есть фоновый поток, который должен быть отключен, прежде чем порт может быть снова открыт, это занимает время.Время не предсказуемо.

Метод Close () может легко заблокироваться, если в данный момент выполняется обработчик события DataReceived.Самый типичный способ получить тупик - это вызвать Control.Invoke () в обработчике событий.Убедитесь, что вы не используете код в обработчике событий, который блокирует или требует переключения контекста потока.Использование BeginInvoke () - это нормально.

Невозможность уничтожить программу вызвана проблемой в драйвере устройства последовательного порта.Запустите Taskmgr.exe, вкладку «Процесс», «Просмотр + Выбор столбцов» и отметьте «Ручки».Если после уничтожения программы вы увидите столбец Handles, показывающий 1, то драйвер последовательного порта будет зависать от запроса ввода-вывода, который он не завершил.Процесс не может завершиться до тех пор, пока не завершатся все его потоки режима ядра.

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

Другая типичная проблема с эмуляторами USB заключается в том, что их так легко отключить во время использования,Это работает примерно так же, как извлечение флэш-накопителя из гнезда, пока Windows пишет в него.Также было бы хорошим способом повесить драйвер устройства. Версии .NET до версии 4.0 страдают от сердечного приступа в фоновом потоке, когда устройство внезапно исчезает.Недалеко от обновления, рядом с разъемом имеется небольшая табличка с надписью «Не отключайте во время использования!»это практический обходной путь.В любом случае, им будет скучно, но через пару раз.

Кстати, именно поэтому существует значок на панели задач «Безопасное извлечение устройства».Вы получите твердое "Не делай этого!"ошибка, если ваша программа использует используемый порт.Но, конечно, операционная система бессильна заставить пользователей фактически использовать ее.У Apple есть патент на методику, которая делает его безаварийным, обнаруживая пальцы пользователя на устройстве:)

2 голосов
/ 09 ноября 2011

Невозможно?

У меня есть идея: поместить флаг внутри события получения данных, который закроет serialcom изнутри!Просто!

пробую себя сейчас

2 голосов
/ 19 августа 2010

Хотя иногда возникает проблема, что метод SerialPort.Close блокируется, это не должно помешать диспетчеру задач убить ваш процесс. Если вы не можете убить свой процесс, это почти наверняка связано с ошибкой в ​​последовательном USB-драйвере. К сожалению, ваши варианты, скорее всего, таковы:

  • не запрашивать состояние устройства
  • заставить поставщика исправить ошибку
  • обойти проблему, выяснив способ опроса состояния устройства без доступа к последовательному порту
  • обойти эту проблему, получив доступ к устройству другим способом (возможно, прямым манипулированием USB)
2 голосов
/ 19 августа 2010

До выхода .Net 4.0 многое могло пойти не так с USB на устройства SerialPort (аварийная программа / система и т. Д.). Было легко проверить ошибки, потянув USB-адаптер с активным портом.

Недавно я провел несколько тестов, используя .Net 4.0, и это исправлено (конечно, улучшено) ??? Тест был простой RX / TX через USB SerialPort с обратной связью, и вытащить USB-адаптер во время использования. Моя программа не вылетала, и я смог снова открыть порт! Это серьезное улучшение.

1 голос
/ 19 августа 2010

Вот ссылка с множеством других ссылок на эту проблему и (возможные) решения:

http://www.vbforums.com/showthread.php?t=558000

1 голос
/ 19 августа 2010

А как насчет использования потока BackGround для опроса устройства, чтобы оно не мешало выходу из приложения?

...