Последовательные порты датируются каменным веком вычислений. Вот где вы подключили свой телетайп ASR-33, чтобы начать печатать в своей программе на Фортране. Электрический интерфейс очень прост. Так же и Windows API для использования последовательного порта из вашего собственного кода. Практически любая среда выполнения поддерживает их.
USB полностью заменил оборудование последовательного порта. У него гораздо более продвинутый логический интерфейс к машине, поддерживающий множество различных типов устройств. Кроме того, он поддерживает Plug and Play, позволяя операционной системе определять, когда устройство подключено или удаляется, а также автоматически устанавливать драйвер устройства и т. Д.
Такая гибкость имеет свою цену, однако для использования USB-устройства всегда требуется драйвер устройства. Драйверы устройств не созданы равными. Разные драйверы требуют разных способов общения с устройством. Обычно это делается через DeviceIoControl () или Read / WriteFile (), но это очень непрозрачные функции API. В первые дни USB производители устройств поставляли DLL, которая предоставляла богатый API, чтобы скрыть детали реализации.
Это не сработало, производители не очень хорошо пишут хорошие API, и им точно не нравится их поддержка . Таким образом, хорошим решением будет поддержка стандартного API, который доступен на любом компьютере, поддерживается любой средой выполнения, документируется и поддерживается кем-то другим. Как и API последовательного порта.
Это не сработало, производители не очень хорошо пишут драйверы устройств, эмулирующие последовательные порты. Самым большим недостатком API является то, что он не поддерживает Plug and Play. Основная поддержка для него отсутствует, ведь у оборудования последовательного порта нет логического интерфейса для его поддержки. Существует некоторая поддержка обнаружения того, что устройство подключено через аппаратную линию рукопожатия DTR, но no не поддерживает вообще, чтобы обнаружить, что порта больше нет.
Проблема с отсоединением USB-устройства. В идеальном мире эмулятор, встроенный в драйвер устройства, будет просто делать вид, что последовательный порт все еще там, пока не будет закрыт последний дескриптор на устройстве. Это было бы логичной реализацией, учитывая, что нет способа вызвать событие Plug and Play. По какой-то странной причине это кажется трудным для реализации. Большинство драйверов USB используют непристойные ярлыки, они просто заставляют устройство исчезать , даже когда оно используется .
Это разрушает любой код режима пользователя, который использует устройство. Как правило, написано, чтобы предположить, что это настоящий последовательный порт, и реальные последовательные порты не исчезают внезапно. По крайней мере, без рисования ярко-синей искрой. То, что идет не так, довольно непредсказуемо, потому что это зависит от того, как драйвер отвечает на запросы на устройстве, которого больше нет. Неполучаемое исключение в рабочем потоке, запущенном SerialPort, было обычной ошибкой. Похоже, ваш драйвер действительно ошибается, он генерирует код возврата ошибки по запросу драйвера MJ_CLOSE. Что довольно логично для водителя, ведь устройства там больше нет, но он совершенно неразрешим с вашей стороны. У вас есть ручка, и вы не можете ее закрыть. Это ручей без весла.
В каждом крупном выпуске .NET был небольшой патч для классов SerialPort, чтобы попытаться немного минимизировать страдания. Но есть ограниченное количество возможностей, которые Microsoft может сделать, улавливая все ошибки и притворяясь, что они не произошли, в конечном итоге приводит к тому, что класс больше не дает хорошей диагностики, даже с хорошим драйвером.
Итак, практические подходы:
- всегда используйте значок «Безопасное извлечение устройства» в Windows
- используйте последнюю версию .NET
- обратитесь к поставщику и попросите обновить драйвер
- продавцы канав, которые поставляют паршивых водителей
- скажите своим пользователям, что только из-за того, что это only , что вы можете сделать с устройством USB, отключение его не решает никаких проблем
- делает закрытие порта простым идоступный в вашем пользовательском интерфейсе
- , приклейте USB-разъем к порту, чтобы он не мог быть удален
5-ая пуля - это также проблема программистов.Написание кода последовательного порта не просто, оно сильно асинхронно, и с потоком пула потоков, который запускает событие DataReceived, трудно иметь дело.Когда вы не можете диагностировать проблему программного обеспечения, вы склонны обвинять аппаратное обеспечение.Там очень мало, вы можете сделать с оборудованием, но отключите его.Плохая идея.Теперь у вас есть две проблемы.