3

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

我目前的结构是:

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

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

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 个字节。如果我在我的一切工作正常之前提出Thread.Sleep(1000)权利。SerialPort.Read(...)

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

4

3 回答 3

11

这是意料之中的;大多数 IO API 只允许您指定上限- 它们需要返回至少一个字节,除非它是 EOF ,在这种情况下它们可以返回非正值。为了补偿,你循环:

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;
}

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

请注意,我还删除了refon responseBytes- 你不需要那个(你不重新分配那个值)。

于 2013-05-08T11:54:23.603 回答
1

尝试将超时更改为InfiniteTimeout.

于 2013-05-08T11:54:16.827 回答
0

如果在 SerialPort.ReadTimeout 之前没有可用的字节,SerialPort.Read 将引发 TimeoutException。所以这个方法准确地读取所需的数字或字节,或者抛出异常:

    public byte[] ReadBytes(int byteCount) {
        try
        {
            int totBytesRead = 0;
            byte[] rxBytes = new byte[byteCount];
            while (totBytesRead < byteCount) {
                int bytesRead = comPort.Read(rxBytes, totBytesRead, byteCount - totBytesRead);
                totBytesRead += bytesRead;
            }



            return rxBytes;
        }
        catch (Exception ex){

            throw new MySerialComPortException("SerialComPort.ReadBytes error", ex);            
        }
    }
于 2016-06-14T08:04:26.750 回答