请求的行为:我想听听提议的、通用的解决方案,用于在流/序列端口上接收到特定缓冲区之前挂起调用线程。目前,我不担心超时等问题,但我需要一些强有力的东西。
尝试的方法:
Class myClass
{
private SerialPort _port; //Assume configured and connected.
public void WaitFor(byte[] buffer)
{
int bufferLength = buffer.Length;
byte[] comparisonBuffer = new byte[bufferLength];
while(true)
{
if(_port.BytesToRead >= bufferLength)
{
_port.Read(comparisonBuffer, 0, bufferLength);
if (comparisonBuffer.SequenceEqual(buffer)) { return; }
}
}
}
{
我已经在这方面取得了相当大的成功,但它只是有一个“黑客”的感觉。它经常给我带来麻烦。我认为这是因为我不能保证在预期的数据包之前或之后都没有收到其他数据,所以这个方法自然会导致读取流的不同步。在这种情况下,我不想丢失前导/尾随数据,但方法应该释放线程。
我需要在过程性中实现,这样事件驱动方法就不会真正适合我。在一般意义上,我希望能够实现;
Do thing;
WaitFor(mybuffer);
Do other thing;
最佳答案
SerialPort.Read()
已经阻塞,直到至少到达一个字节。因此,您不需要(也不应该)像现在这样使用BytesToRead
—您引入了一个可怕的繁忙等待循环。
相反,可以这样做:
// Reads 'count' bytes from a serial port into the specified
// part of a buffer. This blocks until all the bytes have been read.
public void BlockingRead(SerialPort port, byte[] buffer, int offset, int count)
{
while (count > 0)
{
// SerialPort.Read() blocks until at least one byte has been read, or SerialPort.ReadTimeout milliseconds
// have elapsed. If a timeout occurs a TimeoutException will be thrown.
// Because SerialPort.Read() blocks until some data is available this is not a busy loop,
// and we do NOT need to issue any calls to Thread.Sleep().
int bytesRead = port.Read(buffer, offset, count);
offset += bytesRead;
count -= bytesRead;
}
}
下面是如何根据
BlockingRead()
实现原始代码的方法:public void WaitFor(SerialPort port, byte[] buffer)
{
byte[] comparisonBuffer = new byte[buffer.Length];
while (true)
{
BlockingRead(port, comparisonBuffer, 0, comparisonBuffer.Length);
if (comparisonBuffer.SequenceEqual(buffer))
return;
}
}
关于c# - WaitFor() - 如何等待特定缓冲区到达Steam/SerialPort?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39329448/