Последовательный порт и безопасный дескриптор ObjectDisposedException закрыты - PullRequest
0 голосов
/ 26 декабря 2009

Я получаю данные от устройства, отправляющего информацию через последовательный порт, и получаю следующее исключение: «Безопасный дескриптор ObjectDisposedException закрыт». Это может произойти в течение нескольких секунд или нескольких минут, и, похоже, не существует шаблона. Другая вещь, которая случается, - то, что это прекратит получать данные без исключения, и я могу видеть на вкладке окна вывода 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 ]

1 голос
/ 26 декабря 2009

Ваш поток очень короток, он живет ровно столько времени, сколько требуется, чтобы открыть последовательный порт, а затем завершается. И когда это произойдет, ваш последовательный порт будет удален.

Вот как я это вижу. Вы используете подход, основанный на событиях (обработка события DataReceived), в этом случае вам не нужен другой поток, который дорог с точки зрения инфраструктуры и ресурсов ОС. В вашем случае просто избавьтесь от объекта Thread и вызовите serialPort.Open() напрямую. Вы получите DataReceived события в вашей существующей теме.

0 голосов
/ 03 марта 2013

Зарегистрируйте обработчик необработанных исключений в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...