Проблемы с классом SerialPort в .NET - PullRequest
2 голосов
/ 22 марта 2012

Я пытаюсь выяснить, почему некоторые адаптеры последовательного порта USB не работают с .NET . Поведение затронутых адаптеров после SerialPort.Write(). Вызов любого из SerialPort.Readxxx() методы вызывают блокировку метода до примерно ReadTimout. Обходной путь, который я обнаружил, состоит в том, чтобы использовать цикл для блокировки, пока BytesToRead <= 0, и тогда все работает как положено. Почему?

Я собрал несколько журналов отладки , используя Sysinternals ' Portmon . Почему это происходит?

without.log = bad behavior/bad USB adapter
with.log = with the while loop/bad USB adapter
ftdi.log = good behavior/good USB adapter

Я написал две нативные реализации ReadByte () и теперь могу лучше охарактеризовать проблему. Если для ReadIntervalTimeout и ReadTotalTimeoutMultiplier задано значение MAXDWORD ReadFile (), это должен подождать, пока байт не окажется в буфере приема, и вернуться, как описано в MSDN Страница структуры COMMTIMEOUTS.

Журналы Portmon показывают, что именно так ReadByte () настраивает последовательный порт. Но если буфер приема пуст, когда ReadFile () вызван ReadFile (), он ждет, пока ReadTotalTimeoutConstant, а затем возвращается. Microsoft ReadByte () также устанавливает событие Comm; Журналы Portmon ясно показывают, что событие запускается, но ReadByte () никогда не читает буфер приема. Я реализовал это в своей родной версии ReadByte (), и она отлично работает с соответствующим адаптером USB-to-serial.

Собственный ReadByte ()

1 Ответ

1 голос
/ 22 марта 2012

Лучшей идеей для чтения SerialPort является использование асинхронного метода:

_port = new SerialPort();
_port.DataReceived += new SerialDataReceivedEventHandler(OnComPortDataReceived);

void OnComPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
   byte[] ba = new byte[_port.BytesToRead];
   total = _port.Read(ba, 0, _port.BytesToRead);
}
...