我正在尝试诊断为什么某些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转串口适配器完美配合。
答案 0 :(得分:1)
阅读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);
}