开发者

Serial Port - I cannot call form and make ShowDialog in the method of port_received?

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 th开发者_JS百科e 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. 
}


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#?


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜