1

I am listening the port and Once I receive the message doing some of processing than inserting into the database. All good so far. The issue is that into the method of port_received I'd like to popup the form of showing that the device received message and depends user click the OK and seeing the message. And at the background of the popup form there is a timer and closing the form in 2 sec unless user doesnt click the button of see the message. I am calling the form than .ShowDialog() after that I am loosing my serial port communication. If I use .Show() I cannot see the properly some of code:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    data = comport.ReadLine();

    ReceiveMessagePopup popUp = new ReceiveMessagePopup(data);
    popUp.Location = new Point(150, 150);
    popUp.ShowDialog();
    /// after that code I cannot do anything even cannot show any MessageBox. 
}
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
memz
  • 45
  • 11
  • try: if(popUp.ShowDialog() == DialogResult.OK) { //Do s.t } else { //Do s.t else } Hth. – Thinhbk Sep 16 '11 at 02:00
  • did not work. I do that method in baseform and once received the message calling the messageRecievedForm by ShowDialog and there are 2 button OK or No . doesnt matter what I click because I am loosing the communication soon the MessageBoxForm appears. – memz Sep 16 '11 at 02:05
  • ShowDialog brings up a Modal Dialog box. I am unsure what isn't working when you just use Show. ShowDialog **will** block. – Mark Hall Sep 16 '11 at 02:28
  • The event is raised on a secondary thread, so I assume it's creating a new message pump etc. on that thread when the dialog is shown... Invoke should be used to get the UI thread to show the dialog instead – Matt Sep 16 '11 at 02:43

2 Answers2

1

I would not put a ShowDialog or any other UI management in that method as it can be raised many times as soon as data is received.

I think that event handler should just receive and store the data somewhere and the ShowDialog or other notification or UI handling should be done out of that method.

see here for examples on how to use with that event handler and save the incoming data:

How do I use dataReceived event of the SerialPort Port Object in C#?

Community
  • 1
  • 1
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • I can understand what you're saying. But the thing is that I have to popup the message and show that the message has been received to the user. The DotNet MessageBox is working perfectly but the thing is to call the form and showing for a while. How could able to call the form meanwhile? – memz Sep 16 '11 at 03:41
  • then look at @Matt's answer which is very complete. – Davide Piras Sep 16 '11 at 03:43
0

From the MSDN article on SerialPort.DataReceived

"The DataReceived event is raised on a secondary thread when data is received from the SerialPort object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke, which will do the work on the proper thread."

Use Control.BeginInvoke to execute code on the main UI thread to show the dialog. e.g.

assuming this code is in a class that inherits from Form

var data = comport.ReadLine();

_buffer.Append(data);

if (_buffer.IsValid)
{
    BeginInvoke((Action) (() =>
                                {
                                    ReceiveMessagePopup popUp = new ReceiveMessagePopup(buffer);
                                    popUp.Location = new Point(150, 150);
                                    popUp.ShowDialog();
                                }));
}

You don't want to do long running tasks in the event, and as Davide points out, showing the dialog every time the event is raised is probably not a good idea, as you may get many events raised, even for a single line of data from the serial port, so that's why I would add the data read from the port to a buffer, and if the buffer is valid (e.g. contains a whole line/message/packet/whatever) then show the dialog

Matt
  • 2,984
  • 1
  • 24
  • 31