微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – SerialPort.Read(byte [],int32,int32)没有阻塞但我想要它 – 我该如何实现?

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

我目前的结构是:

>发送命令
>读回指定字节数
>继续申请

但是,当我使用SerialPort.Read(byte [],int32,int32)时,该函数没有阻塞.因此,例如,如果我调用MySerialPort.Read(byteBuffer,bytesExpected);,则函数返回小于指定的bytesExpected数.这是我的代码

public bool ReadData(byte[] responseBytes,int bytesExpected,int timeOut)
{
    MySerialPort.ReadTimeout = timeOut;
    int bytesRead = MySerialPort.Read(responseBytes,bytesExpected);
    return bytesRead == bytesExpected;
}

我将此方法称为:

byte[] responseBytes = new byte[13];
if (Connection.ReadData(responseBytes,13,5000))
    ProduceError();

我的问题是,我似乎无法像我所说的那样读取完整的13个字节.如果我在我的SerialPort.Read(…)之前放置一个Thread.Sleep(1000),一切正常.

如何超出timeOut或读取指定的字节数,如何强制Read方法阻塞?

解决方法

这是预期的;大多数IO API允许您仅指定上限 – 它们只需返回至少一个字节,除非它是EOF,在这种情况下它们可以返回非正值.要补偿,你循环:

public bool ReadData(byte[] responseBytes,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;
}

唯一的问题是您可能需要通过使用秒表或类似方法来减少每次迭代的超时,以查看已经过了多少时间.

请注意,我还删除了responseBytes上的引用 – 您不需要它(您不重新分配该值).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐