我有一个使用 RS-232 从 radio 接收数据的应用程序。这些 radio 使用 API 与多个客户端通信。为了使用 radio ,我创建了一个库来与它们通信,其他软件可以使用它,只需对正常的 SerialPort 连接进行最小的更改。该库从 SerialPort 对象读取数据,并根据接收到的 radio 将传入数据插入不同的缓冲区。收到的每个数据包都包含一个 header ,指示其长度、来源等。
我首先从端口读取固定长度的 header 并对其进行解析。在 header 中,数据的长度在数据有效负载本身之前定义,所以一旦我知道数据的长度,我就会等待那么多的数据可用,然后读入那么多的字节。
示例(标题中的其他元素被省略):
// Read header
byte[] header = new byte[RCV_HEADER_LENGTH];
this.Port.Read(header, 0, RCV_HEADER_LENGTH);
// Get length of data in packet
short dataLength = header[1];
byte[] payload = new byte[dataLength];
// Make sure all the payload of this packet is ready to read
while (this.Port.BytesToRead < dataLength) { }
this.Port.Read(payload, 0, dataLength);
显然空端口坏了。如果由于某种原因数据从未到达,线程将锁定。我还没有遇到这个问题,但我正在寻找一种优雅的方法来做到这一点。我的第一个想法是添加一个在 while 循环之前启动的短计时器,并在它结束时设置一个 abortRead 标志,这将中断 while 循环,如下所示:
// Make sure all the payload of this packet is ready to read
abortRead = false;
readTimer.Start();
while (this.Port.BytesToRead < dataLength && !abortRead) {}
此代码需要尽可能快地处理持续不断的传入数据流,因此将开销保持在最低水平是一个问题,并且想知道我是否正确地执行了此操作。
最佳答案
您不必运行此 while 循环,Read
方法会为您填充缓冲区,或者如果缓冲区未在其中填充,则会抛出 TimeoutException
SerialPort.ReadTimeout
时间(您可以根据需要进行调整)。
但是一些一般性的评论 - 你的 while 循环会导致密集的 CPU 工作,在几毫秒内它会花费数据到达你会有成千上万的 while 循环迭代,你应该添加一些 Thread .在里面 sleep
。
关于c# - 在C#中等待来自串口的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41622117/