C# 读取串行端口时引发IO操作中止错误

C# 读取串行端口时引发IO操作中止错误,c#,.net,serial-port,ioexception,C#,.net,Serial Port,Ioexception,我们正在尝试使用.Net串行端口类读取连接到串行端口的外部设备(本例中为磅秤)写入的数据 首先,我们初始化串行端口,如下所示: InitializeSerialPort() { if ((serialPort != null) && (serialPort.IsOpen)) { serialPort.Close(); serialPort.Dispose(); serialPort = null; }

我们正在尝试使用.Net串行端口类读取连接到串行端口的外部设备(本例中为磅秤)写入的数据

首先,我们初始化串行端口,如下所示:

InitializeSerialPort()
{
   if ((serialPort != null) && (serialPort.IsOpen))
   {
       serialPort.Close();
       serialPort.Dispose();
       serialPort = null;
   }

        serialPort = new SerialPort("COM2", 9600, Parity.None, 8,
                                    StopBits.One) { Handshake = Handshake.None };
        serialPort.DataReceived += serialPort_DataReceived;
        serialPort.NewLine = "\r";
}
我们正在使用后台工作线程,通过在串行端口上发送一个命令(由称重秤理解),以连续的间隔轮询设备。一旦我们发送了命令,连接到串行端口的设备就会响应输出。我们调用SerialPort类的ReadLine API,以获取设备在DataReceived事件中写入的串行端口上的数据,如下面的代码段所示:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        data = serialPort.ReadLine();
    }
    catch(System.IO.IOException ex)
    {
        //since serial port reading threw an error so there is no value to be parsed hence exit the function.
        return;
    }
    //if no error then parse the data received
}
我正在使用.NETFramework 4.0的
System.IO.Ports.SerialPort
类。我可以看到很多人在其他论坛上发布这个问题,但没有具体的解决方案。他们中的一些人将.Net串行端口类定义为buggy,微软迄今尚未修复该类错误。提到此错误的论坛之一是


我也尝试了发布的解决方案,但没有任何帮助。如果其他人遇到此问题或其解决方案,我需要一些输入。

我们可以通过锁定serialPort_DataReceived方法中的代码来解决此问题

Object lockObject = new Object();
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    lock(lockObject)
    {
        try
        {
            data = serialPort.ReadLine();
        }
        catch(System.IO.IOException ex)
        {
            //since serial port reading threw an error so there is no value to be parsed hence exit the function.
            return;
        }
    }
    //if no error then parse the data received
}
我们已将轮询串行端口上连接的设备的轮询间隔设置为10秒。可能在
serialPort\u DataReceived
方法中存在的整个代码有时需要10秒以上的时间。我们无法确切地确定这一事实,因为它并非每次都发生


因此,我们使用C#中的lock关键字将整个代码段锁定在
serialPort_DataReceived
方法中,以确保从串口接收的新数据的新执行不会启动,除非旧的读取尚未完成。在试用和出错的基础上实现该代码后,问题得到了解决。如果其他人遇到这样的问题,希望这也能帮助他们。

在串行端口忙于接收数据时关闭串行端口,可能会出现此异常。您特意编写了这样的代码,调用Close()和Dispose()方法。不要这样做。如果您的代码在初始化时调用InitializeSerialPort(),那么这就是一个bug。改为抛出InvalidOperationException,以便您可以诊断此错误。嗨,Hans,谢谢您的快速响应。仅供参考,InitializeSerialPort方法仅在应用程序启动时调用一次,以初始化串行端口对象。因此,读取已处理对象上的串行端口是不可能的。