我在C#中遇到虚拟串口问题:当我调用Write函数时,它会自动抛出TimeOutException,但客户端会收到数据。
它只发生在虚拟端口上(我使用来自HDDSoftware的免费虚拟串行端口,桥接COM12< - > COM13)。我用Visual Studio打开COM12,用Hercules打开COM13。应用程序抛出超时异常,但Hercules收到消息。
如果设置1000ms或1000000ms的读/写端口超时,则无关紧要。
谢谢!
using (SerialPort port = new SerialPort("COM13"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
port.ReadTimeout = 10000;
byte[] buffer = Encoding.ASCII.GetBytes("HELLO WORLD");
try
{
port.Write(buffer, 0, buffer.Length);
}
catch(TimeoutException)
{
Console.WriteLine("Write timeout");
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
try
{
byte[] buf = new byte[100];
port.Read(buf, 0, 1);
}
catch(IOException)
{
Console.WriteLine("Read timeout");
}
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
}
经过几次测试(将Write放入try-catch)后,Read操作也会立即抛出TimeOutException。
这是我在运行测试时得到的。它应该是: 12点16分06秒 (读取超时) 12时16分16秒
答案 0 :(得分:2)
port.Write(buffer, offset, count);
由设备驱动程序决定如何实现它。但我知道的所有内容都遵循以下规则:允许基础WriteFile()调用返回* lpNumberOfBytesWritten< nNumberOfBytesToWrite。换句话说,写不是"事务性的"。
一个不错的心智模型是Write()一次从缓冲区写入一个字节, count 次。在某些时候,完全不可预测的时候,当驱动程序的发送缓冲区填满容量并且不能存储另一个字节时,再写一个字节将停止。最终触发异常。
所以缓冲区的部分仍然会到达另一端。您无法分辨SerialPort类的哪个部分。超时是一个很难恢复的严重沟通失败。如果那是一个show-stopper,那么你需要考虑一次写一个字节(很好,串口慢)或者注意WriteBufferSize - BytesToWrite来检查缓冲是否适合并实现你自己的超时。
答案 1 :(得分:0)
正如Hans Passant所说,虚拟COM软件存在问题。我尝试使用Eltima Software的Virtual Serial Port并且工作正常!