Обнаружение, когда SerialPort отключается

У меня есть открытый SerialPort и получать данные через событие DataReceived .

Есть ли способ обнаружить, отключен ли SerialPort ?

Я пробовал события ErrorReceived и PinChanged но не повезло.

В дополнение к этому, SerialPort.IsOpen возвращает true при физическом отключении.

USB-последовательные порты – огромная боль. См. Например, этот вопрос . Я не уверен, действительно ли это было исправлено с .NET 4.0, но в тот же день, когда я пытался разобраться с проблемой разъединения, сбой всей программы с чем-то вроде этого:

 public class SafeSerialPort : SerialPort { private Stream theBaseStream; public SafeSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) : base(portName, baudRate, parity, dataBits, stopBits) { } public new void Open() { try { base.Open(); theBaseStream = BaseStream; GC.SuppressFinalize(BaseStream); } catch { } } public new void Dispose() { Dispose(true); } protected override void Dispose(bool disposing) { if (disposing && (base.Container != null)) { base.Container.Dispose(); } try { if (theBaseStream.CanRead) { theBaseStream.Close(); GC.ReRegisterForFinalize(theBaseStream); } } catch { // ignore exception - bug with USB - serial adapters. } base.Dispose(disposing); } } 

Извиняюсь за то, с кем я это адаптировал, кажется, я не заметил этого в своем коде. Проблема, очевидно, связана с тем, как .NET обрабатывал базовый stream в случае исчезновения последовательного порта. Казалось, вы не сможете закрыть stream после отсоединения последовательного порта.

Другая страtagsя, которую я использовал, заключалась в создании небольшой программы, которая выполняла только часть последовательной связи, и открыла WCF-сервис для моей основной программы для подключения. Таким образом, когда USB-последовательный адаптер выходит из строя и выдает сообщение о программе связи, я могу просто автоматически перезапустить его из моей основной программы.

Наконец, я не знаю, почему никто никогда не продавал блокирующий USB-порт, чтобы избежать всей случайной проблемы разъединения, особенно с USB-последовательными адаптерами!

Я также столкнулся с проблемой необъяснимого исключения (и не смог обнаружить / обойти проблему в коде), как только USB-последовательный адаптер был отключен. Я могу подтвердить, что решение от Mattt Burland работает.

Упрощенная версия:

 class SafeSerialPort : SerialPort { public new void Open() { if (!base.IsOpen) { base.Open(); GC.SuppressFinalize(this.BaseStream); } } public new void Close() { if (base.IsOpen) { GC.ReRegisterForFinalize(this.BaseStream); base.Close(); } } protected override void Dispose(bool disposing) { try { base.Dispose(disposing); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } } 

Проблема заключается в том, что значение IsOpen только к false когда выполняется метод Close .

Вы можете попробовать получить сообщение WM_DEVICECHANGE и использовать это.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363480(v=vs.85).aspx

Если устройство, к которому вы подключаетесь, использует контакт CD, вы можете следить за тем, чтобы это изменилось (другие контакты могут применяться для некоторых устройств, использующих управление streamом). Если нет, то на самом деле нет окончательного способа сделать это.

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

Я решил эту проблему с простым фоном. Я постоянно проверяю / устанавливаю все текущие порты в массив, и если новые порты отличаются от моего массива портов, я получаю измененные порты из этих 2 массивов.

Пример:

 // global variable List oldPorts = new List(); // contains all connected serial ports private void bgw_checkSerialPorts_DoWork(object seder, DoWorkEventArgs e) { while (true) { string[] currentPorts = SerialPort.GetPortNames(); // get all connected serial ports string[] diffPorts = currentPorts.Except(oldPorts.ToArray()); // get the differences between currentPorts[] and oldPorts-list if (diffPorts.Length > 0) { // iterate all changed ports for (int i = 0; i < diff.Length; i++) { // check if changed port was in old list if (oldPorts.Contains(diff[i])) { // port in diff[] was removed } else { // port in diff[] is a new device } } } oldPorts = currentPorts.ToList(); // update oldPortlist // check every 100ms Thread.Sleep(100); } } 

Используйте флаг C # SerialPort.CDHolding.

Поэтому сохраните bool до флага lastCDHolding перед вашим циклом открытия и чтения.

После того, как вы прочитали тест SerialPort.CDHolding! = LastCDHolding, чтобы уловить изменения или просто проверить SerialPort.CDHoldin == false, чтобы обнаружить, что порт был закрыт.

  • Программно добавить новый столбец в DataGridView
  • InvalidOperationException - объект в настоящее время используется в другом месте
  • Внедрение MVC с помощью Windows Forms
  • Изменение размера windows без полей в нижнем правом углу
  • Как создавать и подключать пользовательские кнопки / элементы управления с линиями, используя формы окон
  • Как показать текст в поле со списком, если ни один элемент не выбран?
  • Как создать пользовательский элемент редактора PropertyGrid, который открывает форму?
  • Свойство привязки для управления в Winforms
  • Как заполнить пустой текстовый текст по умолчанию?
  • Как я могу получить полосы прокрутки в Picturebox
  • Правильный способ изменения языка во время выполнения
  • Interesting Posts

    WCF, тип возврата интерфейса и известные типы

    Метод, чтобы узнать, если кто-то регистрирует разговор на Yahoo Messenger

    Как установить автоответчики на определенные дни в Microsoft Outlook?

    Идентификация примитивных типов в шаблонах

    Проблема десериализации с помощью DataContractJsonSerializer

    Присоединение видео в командной строке

    Определения Truststore и Keystore

    База данных – Версии данных

    Outlook не показывает уведомления на рабочем столе при получении сообщения

    Создание вкладок с использованием fragmentов теперь, когда TabActivity устарела

    jQuery изменение цвета цветной пользовательский прокрутка

    Как я основываю правило перспективы на число адресов «Кому:»?

    Матричное умножение: малая разница в размере матрицы, большая разница в таймингах

    iOS 7 | Панель навигации / кнопки панели инструментов очень близко к строке состояния

    Как изменить IP-адрес, чтобы указать на localhost?

    Давайте будем гением компьютера.