0
votes

We are trying to read data written by an external device (weighing scale in this case) connected to serial port using .Net serial port class.

First we initialize the serial port as below:

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";
}

We are using background worker thread to poll the device on continuous interval by sending a command(understood by the weighing scale) on the serial port. As soon as we send the command the device connected to serial port reacts with a response output. We call ReadLine API of SerialPort class to get the data present on the serial port written by the device in the DataReceived event as shown in the code snippet below :

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
}

I'm using System.IO.Ports.SerialPort class of .Net framework 4.0. I can see a number of people posting this issue on other forums but with no specific resolution. Some of them terming .Net Serial port class as buggy which has not been fixed by Microsoft till date. One of the forums where this error is mentioned is here

I also tried the solution posted here but of no help. I need some input if any one else has come across this issue or its resolution.

1
You are liable to get this exception when you close the serial port while it is busy receiving data. You intentionally wrote code to do that, calling the Close() and Dispose() methods. Do not do this. If your code is calling InitializeSerialPort() when it is already initialized then that's a bug. Throw an InvalidOperationException instead so you can diagnose this bug.Hans Passant
Hi Hans, Thanks for your quick response. Just for your information the InitializeSerialPort method gets called only once at the start-up of the application to initialize the serial port object. So reading serial port on an object which has got already disposed is not a possibility.RBT

1 Answers

0
votes

We were able to solve this problem by locking the code inside serialPort_DataReceived method.

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
}

We had set the polling interval to poll the device connected on serial port as 10 seconds. Possibly the entire code present inside serialPort_DataReceived method was sometimes taking more than 10 seconds. We were not able to exactly establish this fact as it was not happening every time may be.

So we locked the entire piece of code inside serialPort_DataReceived method using lock keyword in C# to ensure that the new execution for new data received from serial port doesn't start unless the older reading hasn't finished. The issue got resolved after implementing this code on trial and error basis. Hope this helps others as well if they come across such an issue.