0

I have the following code

    private SerialPort _port = null;

    public SerialReader(string portname, int baudrate, Parity parity, int databits, StopBits stopbits, int readTimeoutMs = 10000)
    {
        //Set serial-port
        _port = new SerialPort();
        _port.PortName = portname;
        _port.BaudRate = baudrate;
        _port.Parity = parity;
        _port.DataBits = databits;
        _port.StopBits = stopbits;
        _port.ReadTimeout = readTimeoutMs;
        _port.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceivedNew);
        _port.Open();
    }

    private void SerialPort_DataReceivedNew(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort port = (SerialPort)sender;
        _buffer = new byte[port.BytesToRead];
        try
        {
            port.Read(_buffer, 0, _buffer.Length);
        }
        catch (System.TimeoutException ex)
        {
            bool doDispose = true;
            if (ReadTimeout != null)
                ReadTimeout(ex, out doDispose);

            if(doDispose)
                this.Dispose();
            return;
        }
        ///////////
    }

If the connected devices sends data all work fine, but if I unplug it, the program waits for other data forever without throwing System.TimeoutException (documentation says that it should throw exception).

I verified this by placing a breakpoint on bool doDispose = true; and it is never reached.

The assembly is compiled as "Debug".

Is this a bug or am I missing something?

Edit

It is possible that SerialPort_DataReceivedNew isn't called because no data is actually received, if this is the case, how can I catch errors?

Edit 2

To make it work I edited the code like this:

Added methods BeginGetData and PollSerialPort

    public void BeginGetData()
    {
        _port.Open();
        Thread pollingThread = new System.Threading.Thread(new System.Threading.ThreadStart(PollSerialPort));
        pollingThread.Start();
    }

    private void PollSerialPort()
    {
        while (this.SerialPort_DataReceivedNew()) ;
    }

And edited SerialPort_DataReceivedNew

    private bool SerialPort_DataReceivedNew()
    {
        _buffer = new byte[_port.BytesToRead];
        try
        {
            if (_port.Read(_buffer, 0, _buffer.Length) == 0)
                _port.Write("\0");
        }
        catch (System.TimeoutException ex)
        {
            bool doDispose = true;
            if (ReadTimeout != null)
                ReadTimeout (this, out doDispose);

            if (doDispose)
            {
                _port.Close();
                return false;
            }
            return true;
        }
        ///////////
    }

On _port.Write("\0"); I have the TimeoutException

Matteo Umili
  • 3,412
  • 1
  • 19
  • 31

1 Answers1

0

Put your breakpoint earlier to see if DataReceived is ever called. Even if it is, and there is no data (weird) your buffer size is zero because BytesToRead is zero so it will never timeout. Try polling the serial port in a timer event instead.

Graham
  • 799
  • 2
  • 5
  • 14