C# 从串行端口读取时会出现过时数据

C# 从串行端口读取时会出现过时数据,c#,.net,winapi,serial-port,C#,.net,Winapi,Serial Port,我们的C#应用程序通过串行端口与设备通信。该协议是一个类似于请求/响应的简单协议 大多数情况下,一切都正常工作,但在某些机器上,我们有时会遇到以下请求响应的超时和过时数据 我编写了一个单线程控制台应用程序,并设法在虚拟机中可靠地再现了这个问题,在虚拟机中,我将CPU限制在10%左右。该应用程序基本上执行以下操作: _port = new SerialPort( "COM1", 115200, Parity.None, 8, StopBits.One) {

我们的C#应用程序通过串行端口与设备通信。该协议是一个类似于请求/响应的简单协议

大多数情况下,一切都正常工作,但在某些机器上,我们有时会遇到以下请求响应的超时和过时数据

我编写了一个单线程控制台应用程序,并设法在虚拟机中可靠地再现了这个问题,在虚拟机中,我将CPU限制在10%左右。该应用程序基本上执行以下操作:

_port = new SerialPort(
    "COM1",
    115200,
    Parity.None,
    8,
    StopBits.One)
{
    RtsEnable = false,
    DtrEnable = false,
    Handshake = Handshake.None,
    ReadTimeout = 5000
    WriteTimeout = 5000
};

_port.Open();
_port.DiscardInBuffer();
_port.DiscardOutBuffer();


_readBuffer = new byte[1024];

// Send requests periodically...
while (true)
{
    var requestBytes = ...;                 // Encode the request
    _port.Write(requestBytes, 0, requestBytes.Length);

    try
    {
        var responseStream = new List<byte>(1024);
        int count = ...;                        // Calculate number of bytes of the response
        int remainingBytesCount = count;
        while (numberOfBytesReadTotal < count)
        {
            int bytesToRead = Math.Min(_readBuffer.Length, remainingBytesCount);
            int numberOfBytesRead = _port.Read(_readBuffer, 0, bytesToRead);
            if (numberOfBytesRead <= 0)
                break;

            remainingBytesCount -= numberOfBytesRead;

            responseStream.AddRange(_readBuffer.Take(numberOfBytesRead));
        }

        // Parse the response and if it is valid, dump it. Otherwise throw an exception
        var response = ParseResponse(responseStream);
        Console.WriteLine(FormatResponse(response));
    }
    catch (Exception err)
    {
        Console.WriteLine("ERROR OCCURED: " + err);
        Console.WriteLine("Sleep some time, then discard in and out buffers and then proceed");
        Thread.Sleep(10000);
        _port.DiscardInBuffer();
        _port.DiscardOutBuffer();
    }
}
\u端口=新的串行端口(
“COM1”,
115200,
平价,无,
8.
停止位(1)
{
RtsEnable=false,
DtrEnable=false,
握手=握手。无,
读取超时=5000
WriteTimeout=5000
};
_port.Open();
_port.DiscardInBuffer();
_port.DiscardorBuffer();
_readBuffer=新字节[1024];
//定期发送请求。。。
while(true)
{
var requestBytes=…;//对请求进行编码
_写入端口(requestBytes,0,requestBytes.Length);
尝试
{
var responseStream=新列表(1024);
int count=…;//计算响应的字节数
整数剩余字节数=计数;
while(numberOfBytesReadTotal<计数)
{
int bytesToRead=Math.Min(_readBuffer.Length,remainingBytesCount);
int numberOfBytesRead=\u port.Read(\u readBuffer,0,bytesToRead);

if(numberOfBytesRead Unfortunatel,我没有串行端口来尝试任何操作。接收到的事件数据如何?而不是等待(并阻止应用程序)对于同步读取,您可以尝试创建一个事件处理程序并将其附加到DataReceived。这将处理与进程共享CPU时间和停止有关的问题。它是真正的com端口还是usb到com端口?您可以在catch中执行读取(在发生故障时在循环中)协助n刷新,或关闭并重新打开连接。
我认为这不应该发生,因为我丢弃了输入和输出缓冲区。
这就是文档所说的应该发生的吗?我通过谷歌搜索发现了这一点,告诉我如何从SerialPort实现良好的行为:代码看起来很好;但读了@Baltasarq link后,我深感怀疑令人怀疑的是,任何使用串行端口类的代码,无论编写得多么好,都将是可靠的。