问题描述
我就从被通过串行端口发送信息的设备接收数据,我得到这个异常:的ObjectDisposedException安全手柄已经关闭。它可以在几秒钟内发生到几分钟并似乎没有成为一个图案。这种情况发生的另一件事是,它将停止接收,没有例外的数据,我可以在VS IDE输出窗口选项卡,一个线程退出见。我不知道为什么它这样做也。
下面是我如何创建串行端口:
DeviceSerialPort的SerialPort =新DeviceSerialPort(COM1,9600,System.IO.Ports.Parity.None,8,System.IO.Ports.StopBits.One);
serialport.RHDataReceived + =新的EventHandler< DeviceDataEventArgs>(SerialPort_RHDataReceived);
serialport.Open();
这里是串口code:
使用系统;
使用System.Collections.Generic;
使用System.Diagnostics程序;
使用System.IO.Ports;
使用System.Text;
命名空间仪器
{
公共类DeviceSerialPort
{
公共事件的EventHandler< DeviceDataEventArgs> RHDataReceived;
私人的SerialPort _serialPort;
私人字节[] _readBuffer =新的字节[1024];
公共DeviceSerialPort(字符串PORTNAME,诠释波特率,奇偶校验,
INT数据位,停止位停止位)
{
_serialPort =新的SerialPort(PORTNAME,波特率,奇偶校验,数据位,停止位);
_serialPort.DataReceived + =新SerialDataReceivedEventHandler(SerialPort_DataReceived);
}
公共无效的open()
{
_serialPort.Open();
}
私人无效SerialPort_DataReceived(对象发件人,EventArgs的)
{
//的SerialPort SP =(的SerialPort)发送;
INT读取动作= _serialPort.Read(_readBuffer,0,_readBuffer.Length);
如果(_readBuffer [0] == 5)
{
onRHDataReceivedEvent(新DeviceDataEventArgs(_readBuffer [0],_readBuffer [1],_readBuffer [2],_readBuffer [3]));
}
}
保护无效onRHDataReceivedEvent(DeviceDataEventArgs E)
{
如果(RHDataReceived!= NULL)
{
RHDataReceived(这一点,E);
}
}
}
公共类DeviceDataEventArgs:EventArgs的
{
公共字节命令{获得;组; }
公共字节的数据0 {获得;组; }
公共字节数据1 {获得;组; }
公共字节的CRC {获得;组; }
公共DeviceDataEventArgs(CMD字节,字节DATA0,DATA1字节,字节的CRC)
{
命令= CMD;
数据0 = DATA0;
数据1 = DATA1;
CRC = CRC;
}
}
}
您线程很短暂,它一生的时间恰好的长度才能打开串口,然后它完成。而当它,您的串行端口得到处理。
这是我的看法。您正在使用一个基于事件的方法(处理 DataReceived
事件),在这种情况下,你不需要另一个线程,这是昂贵的架构和操作系统方面资源。在你的情况,简单地摆脱了发
的对象,而 serialPort.Open()
直接调用。您将收到在您现有的线程中的 DataReceived
事件。
I am receiving data from a device that's sending information over the serial port and I get this exception: "ObjectDisposedException Safe Handle has been closed". It may happen within seconds to several minutes and there doesn't seem to be a pattern. Another thing that happens is that it will stop receiving data with no exception and I can see in the VS IDE output window tab that a thread has exited. I have no idea why it's doing that also.
Here is how I create the serial port:
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();
And here is the serial port code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Text;
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;
}
}
}
Your thread is very short lived, it lives for exactly the length of time it takes to open the serial port, and then it finishes. And when it does, your serial port gets disposed.
This is how I see it. You're using an event-based approach (handling the DataReceived
event), in which case, you don't need another thread, which is expensive in terms of framework and OS resources. In your case, simply get rid of the Thread
object, and call serialPort.Open()
directly. You will receive the DataReceived
events in your existing thread.
这篇关于串行端口和的ObjectDisposedException安全手柄已经关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!