SerialPort.Read(byte [],int32,int32)没有阻塞,但我希望这样做-如何实现? [英] SerialPort.Read(byte[], int32, int32) is not blocking but i want it to - how do I achieve?

查看:124
本文介绍了SerialPort.Read(byte [],int32,int32)没有阻塞,但我希望这样做-如何实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个用于与测试设备对话的界面.设备通过串行端口进行通讯,并对我发送的每个命令以已知的字节数进行响应.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆