System::IO::Ports::SerialPort::ReadLine() polling problem

I have a problem with a simple application reading a GPS NMEA 2.0 device through the serial port. On the idle event, my delegate function is invoked and reads the serial port, parses the GPS data (no looping in the parsing fucntion) and undates some text fields as well as a compass control. All is well when I randomly generate the GPS text data. In other words, there is a constant and consistant updating of the windows form, with no user interactions. However, when ever, I use the command ReadLine(), the program does not update the windows form, unless I create a mouse event over the form, like move mouse, right click, ect... (any will do). I did some breakpoint checking, and it appears as though the message pump has suspended, unless it receieves a message, which should not happen. If all I do is comment out the ReadLine() function, everything works peachy. BTW, when communicating with the GPS device, the parsing works fine, and there are no comm port exceptions (have a delegate for that, which is utilized by ).

gpsPort.ErrorReceived += gcnew System::IO::Ports::SerialErrorReceivedEventHandler(this,&Form1::gpsError);



Answer this question

System::IO::Ports::SerialPort::ReadLine() polling problem

  • kawing0510

    Yes, I wouldn't use Application.Idle for a call that can block for a while. Using a Timer is a simple workaround.


  • msFlash

    It must be SerialPort day today. ReadLine() is a blocking call, it won't return until the serial device transmits the SerialPort.NewLine character. When it blocks, your form will stop updating. After several seconds, Windows XP will display the "ghost" window, it has "(Not responding)" in the title bar.

    To avoid this, use the DataReceived event to read the modem's response or use the ReadTimeout property. Or make sure your communications are debugged so the modem always sends a response that includes the NewLine character so you'll never block too long.


  • Idanle

    I use the idle event and the System::EventtHandler. Seems to work well for most applications so far (except this one)

    System::Windows::Forms::Application::Idle += gcnew System::EventHandler(this,&Form1::getGpsData);

    Is this a problem

    The delegate function getGpsData directly updates the form controls.

    I can try using the DataReceived event and Control.Invoke (delegate).


  • Karthik Juneni

    Yes, the DataReceived event runs on another thread. So does the ErrorReceived event BTW. You'd need to use Control.Invoke to touch the UI.

    Seeing the Application.Run() call highlighted in green when you pause the program is normal, it indicates that your app is pumping messages as it should and is not hung in ReadLine() or one of your event handlers. What event do you use to execute the code that calls ReadLine()


  • digitalsuperman

    Thanx for the expediant answer. I tried to change updating with the System::EventHandler on the Idle state, to the SerialDataReceivedEventHandler on the DataRecieved event. But the form complained at runtime that the form cannot be updated from a separate thread. I guess this event handler creates an additional thread Currnetly, this is a monolithic program (only the main thread). I do have the ReadTimeout set to 1000ms, and still the same issue. BTW, the program remains responsive as far as user interaction goes (I have several buttons on a separate tab. Did I mention the controls I am attempting to update are in a tab structure ). Also, the title bar never reads "Not Respoding" and no timeout exception occurs. I really think this has to do with the message pump, since if I pause the execution, the green arrow is on the main() function, at the Application.Run function (message pump). Maybe addting the serial reads prevents the Idle message from being sent
  • System::IO::Ports::SerialPort::ReadLine() polling problem