C#虚拟串口写入时出现超时异常

3
我在C#中使用虚拟串口时遇到了问题:当我调用Write函数时,它会自动抛出TimeOutException,但客户端却可以接收到数据。
只有在使用虚拟端口(我使用的是来自HDDSoftware的Free Virtual Serial Ports,带有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中),读操作也会立即抛出TimeOutException。

这是我进行测试时得到的结果。理应是: 12:16:06 (读取超时) 12:16:16

图片描述


@Groo 是的,我看到了并尝试了这些解决方案,但没有帮助。 - tincho87
你能够提供一些读取/写入数据的代码吗? - jbutler483
@tincho87,另外,Timeout异常是读取还是写入? - jbutler483
所以应该是 port.write(buffer,0,buffer.Length) 吗?(其中 buffer 是数组)- 然后使用 'read',你正在使用 port.read(buffer,0,1) 读取缓冲区,然后在另一侧进行连接? - jbutler483
尝试将dataBits设置为8,将Parity设置为none。你还在程序的其他地方声明了端口的name吗? - jbutler483
显示剩余8条评论
2个回答

2
   port.Write(buffer, offset, count);

设备驱动程序决定如何实现此功能。但我所知道的所有驱动程序都遵循以下规则:底层的WriteFile()调用允许返回*lpNumberOfBytesWritten < nNumberOfBytesToWrite。换句话说,写操作不是“事务性的”。一个合理的思维模型是,Write()一次从缓冲区中写入一个字节,重复count次。在某个完全不可预测的时刻,当驱动程序的传输缓冲区填满并不能再存储更多字节时,再写入一个字节将会停止,并最终引发异常。
因此,部分缓冲区仍然可以到达另一端。你无法从SerialPort类中确定哪一部分。超时是一种严重的通信故障,很难恢复。如果这是个无法解决的问题,那么你需要考虑逐个字节地写入(没关系,串口速度慢),或者关注WriteBufferSize - BytesToWrite以检查缓冲区是否适合并实现自己的超时。

嗨,我尝试每次写入一个字节,但第一次写入时,我遇到了TimeOutException异常。在问题中添加的示例中,在Hercules中我只收到“HELLO WORLD”中的“H”。 - tincho87
哦,WriteBufferSize是什么?你将WriteTimeout属性设置为多少了?建议将其设置为读取端口的程序中预期延迟的10倍。在像Windows或Linux这样的按需分页虚拟内存操作系统上,延迟很容易达到数百毫秒。因此,请不要使用小于5000的值。 - Hans Passant
这些值是默认值,但尝试将WriteTimeOut设置为10000,以及相同的WriteBufferSize设置为2048。我不知道虚拟端口出了什么问题。 - tincho87
1
WriteTimeout 的默认值是 0,写入时不应产生 TimeoutException。 显然,您正在使用的软件并不是很可靠。 请联系供应商寻求支持。 - Hans Passant

0
正如Hans Passant所说,这是虚拟COM软件的问题。我尝试使用Eltima Software的虚拟串口,效果很好!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接