문제

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.

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top