串行端口和ObjectDisposedException安全句柄已关闭

时间:2009-12-26 19:16:42

标签: c# .net serial-port .net-3.5

我从通过串口发送信息的设备接收数据,我得到了这个异常:“ObjectDisposedException Safe Handle已经关闭”。它可能在几秒到几分钟内发生,似乎没有一种模式。发生的另一件事是,它将停止接收数据,没有异常,我可以在VS IDE输出窗口选项卡中看到线程已退出。我不知道为什么它也这样做。

以下是我创建串口的方法:

DeviceSerialPort serialport = new DeviceSerialPort("COM1", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
serialport.RHDataReceived += new EventHandler<DeviceDataEventArgs>(SerialPort_RHDataReceived);
serialport.Open();

这是串口代码:

namespace Instrument
{
    public class DeviceSerialPort
    {
        public event EventHandler<DeviceDataEventArgs> RHDataReceived;

        private SerialPort _serialPort;
        private byte[] _readBuffer = new byte[1024];

        public DeviceSerialPort(string portName, int baudRate, Parity parity, 
            int dataBits, StopBits stopBits)
        {
            _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            _serialPort.DataReceived +=new SerialDataReceivedEventHandler(SerialPort_DataReceived);

        }

        public void Open()
        {
            _serialPort.Open();
        }

        private void SerialPort_DataReceived(object sender, EventArgs e)
        {
            //SerialPort sp = (SerialPort)sender;

            int bytesRead = _serialPort.Read(_readBuffer, 0, _readBuffer.Length);


            if (_readBuffer[0] == 5)
            {
                onRHDataReceivedEvent(new DeviceDataEventArgs(_readBuffer[0], _readBuffer[1], _readBuffer[2], _readBuffer[3]));
            }
        }


        protected void onRHDataReceivedEvent(DeviceDataEventArgs e)
        {
            if (RHDataReceived != null)
            {
                RHDataReceived(this, e);
            }
        }

    }

    public class DeviceDataEventArgs : EventArgs
    {
        public byte Command { get; set; }
        public byte Data0 { get; set; }
        public byte Data1 { get; set; }
        public byte Crc { get; set; }

        public DeviceDataEventArgs(byte cmd, byte data0, byte data1, byte crc)
        {
            Command = cmd;
            Data0 = data0;
            Data1 = data1;
            Crc = crc;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

你的线程非常短暂,它的存在时间恰好是打开串口所需的时间,然后就完成了。当它发生时,你的串口就会被处理掉。

这就是我的看法。您正在使用基于事件的方法(处理DataReceived事件),在这种情况下,您不需要另一个线程,这在框架和操作系统资源方面是昂贵的。在您的情况下,只需删除Thread对象,然后直接调用serialPort.Open()。您将在现有主题中收到DataReceived个事件。

答案 1 :(得分:-1)

使用以下命令在form_load中注册未处理的异常处理程序:

AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledException_Handler

并添加处理程序:

'This sub does the magic
Private Sub UnhandledException_Handler(ByVal sender As Object, ByVal args As UnhandledExceptionEventArgs)
    Dim ex As Exception = DirectCast(args.ExceptionObject, Exception)
    Thread.CurrentThread.Suspend()
End Sub