我目前遇到了一个我无法找到答案的问题。我正在控制通过Virtual-ComPort(USB)连接到计算机的设备。对于此通信,我使用System.IO.Ports中的SerialPort类。
这是我初始化端口的方式:
SerialPort SerialPort = new SerialPort();
SerialPort.BaudRate = BaudRate;
SerialPort.DataBits = 8;
SerialPort.Parity = Parity.None;
SerialPort.PortName = SerialPortName;
SerialPort.StopBits = StopBits.One;
SerialPort.ReceivedBytesThreshold = 9;
SerialPort.WriteTimeout = 1500;
SerialPort.ReadTimeout = 1500;
SerialPort.DataReceived += dataReceivedHandler;
SerialPort.Open();
我将接收到的阈值设置为9,因为我知道我可以接收的所有数据都是9个字节,我希望最小化回调次数。这会造成什么伤害吗?
在99,99%的案例中,这确实很有效。但是经过一段随机的时间/命令(通常在几千次操作之后),当数据发送到PC时,我不会收到回调。在这些情况下,不会调用DataReceived处理程序。我通过在dataReceivedHandler的最开头添加一个Debug.WriteLine(" Callback received!")来检查这一点。
我确信数据是由我喜欢控制的设备发送的。这看似"随机"的原因是什么?行为以及如何解决?
我很感激任何建议。
最佳纳米
答案 0 :(得分:2)
使用ReceivedBytesThreshold是一种方便,但它只适用于太阳照耀下,你的背部有一阵微风。您正在跳过需要执行的操作以确保可以工作:
您需要实现流控制,因此不存在设备可能溢出输入缓冲区的情况。尽管现代机器足够快以支持高波特率,但它们无法保证它们总是足够快。丢失处理器几百毫秒是非常有可能的。您应始终设置Handshake属性,以便永远不会发生这种情况。正确的值取决于设备支持的内容,如果您不知道,请始终使用Handshake.RequestToSend。
从不检查错误几乎可以保证您无法诊断此类事故。实现ErrorReceived事件处理程序不是可选的。这是您可以诊断事故的唯一方法,例如UART或设备驱动程序输入缓冲区溢出,导致数据丢失并导致您尝试进行故障排除的麻烦。
ReceivedBytesThreshold始终会为您提供同步问题。你必须确保在两个9字节的块之间的恰当时间开始收听。如果您无法控制程序与设备的启动顺序,那当然很难做到,您很少这样做。一个不错的协议总是为您提供一种同步方式,通常使用指示消息开始的专用字节值。一旦你有了,ReceivedBytesThreshold的值就会完全消失。
从ErrorReceived事件开始,以便在出现问题时知道。购买另一个USB仿真器也应该在你的可能的解决方法列表中占据很高的位置,对它们的驱动程序通常都很蹩脚。