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