SerialPort.Read(byte [],int32,int32)没有阻塞,但我希望这样做-如何实现? [英] SerialPort.Read(byte[], int32, int32) is not blocking but i want it to - how do I achieve?
问题描述
我正在编写一个用于与测试设备对话的界面.设备通过串行端口进行通讯,并对我发送的每个命令以已知的字节数进行响应.
I'm writing an interface for talking to a piece of test equipment. The equipment talks over a serial port and responds with a known number of bytes to each command I send it.
我当前的结构是:
- 发送命令
- 回读指定字节数
- 继续进行申请
但是,当我使用SerialPort.Read(byte [],int32,int32)时,该函数没有阻塞.因此,例如,如果我调用MySerialPort.Read(byteBuffer, 0, bytesExpected);
,则该函数返回的小于指定数量的bytesExpected
.这是我的代码:
However, when I used SerialPort.Read(byte[], int32, int32), the function is not blocking. So, for example, if I call MySerialPort.Read(byteBuffer, 0, bytesExpected);
, the function returns with less than the specified number of bytesExpected
. Here is my code:
public bool ReadData(byte[] responseBytes, int bytesExpected, int timeOut)
{
MySerialPort.ReadTimeout = timeOut;
int bytesRead = MySerialPort.Read(responseBytes, 0, bytesExpected);
return bytesRead == bytesExpected;
}
我这样调用此方法:
byte[] responseBytes = new byte[13];
if (Connection.ReadData(responseBytes, 13, 5000))
ProduceError();
我的问题是,我似乎永远无法像我所说的那样读取全部13个字节.如果在我的SerialPort.Read(...)
前面放一个Thread.Sleep(1000)
,一切正常.
My problem is that I can't ever seem to get it to read the full 13 bytes like I am telling it. If I put a Thread.Sleep(1000)
right before my SerialPort.Read(...)
everything works fine.
如何强制Read
方法阻塞,直到超过timeOut或读取指定的字节数为止?
How can I force the Read
method to block until either the timeOut is exceeded or the specified number of bytes are read?
推荐答案
这是预期的;大多数IO API允许您仅指定上限上限 -只需返回至少一个字节,除非它是EOF,否则可以返回非正值.为了补偿,您可以循环:
That is expected; most IO APIs allow you to specify the upper bound only - they are simply required to return at-least-one byte, unless it is an EOF in which case they can return a non-positive value. To compensate, you loop:
public bool ReadData(byte[] responseBytes, int bytesExpected, int timeOut)
{
MySerialPort.ReadTimeout = timeOut;
int offset = 0, bytesRead;
while(bytesExpected > 0 &&
(bytesRead = MySerialPort.Read(responseBytes, offset, bytesExpected)) > 0)
{
offset += bytesRead;
bytesExpected -= bytesRead;
}
return bytesExpected == 0;
}
唯一的问题是,您可能需要使用Stopwatch
或类似方法来减少每次迭代的超时时间,以查看经过了多少时间.
The only problem is you might need to reduce the timeout per iteration, by using a Stopwatch
or similar to see how much time has passed.
请注意,我还删除了responseBytes
上的ref
-您不需要(不必重新分配该值).
Note that I also removed the ref
on responseBytes
- you don't need that (you don't re-assign that value).
这篇关于SerialPort.Read(byte [],int32,int32)没有阻塞,但我希望这样做-如何实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!