我正在尝试诊断为什么某些USB串行端口适配器不能与.NET一起正常工作。受影响的适配器的行为是在SerialPort.Write()
之后。呼叫任何SerialPort.Readxxx()
方法使该方法阻塞直到大约ReadTimout
。
我发现的解决方法是在BytesToRead
为<= 0
,然后一切正常。为什么?
我已经使用some debug logs'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然后返回。
微软的ReadByte()也设置了一个Comm事件。 Portmon日志清楚地显示了事件正在触发,但是ReadByte()从不读取接收缓冲区。我在本机版本的ReadByte()中实现了此功能,它可以与受影响的USB到串行适配器完美配合。
Native ReadByte()
最佳答案
读取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);
}