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

Mic*_*kus 3 c# serial-port blocking

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

我目前的结构是:

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

但是,当我使用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;
}
Run Code Online (Sandbox Code Playgroud)

我将此方法称为:

byte[] responseBytes = new byte[13];
if (Connection.ReadData(responseBytes, 13, 5000))
    ProduceError();
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ell 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;
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是你可能需要减少每次迭代的超时,通过使用Stopwatch或类似来看看已经过了多少时间.

请注意,我也去掉了refresponseBytes-你不需要说(你不重新分配该值).