简体   繁体   中英

Serial Comms C#

I am writing a C# application to communicate via serial to a microcontroller. I have a few questions on how to handle received messages. Below is the code that I am using at the moment, It received the messages perfectly fine, but I cannot update the Form, or store the data anywhere outside of this method (because it is in another thread).

com.DataReceived += new SerialDataReceivedEventHandler(OnReceived);


public void OnReceived(object sender, SerialDataReceivedEventArgs c) // This is started in another thread...
    {
        com.DiscardOutBuffer();
        try
        {
            test = com.ReadExisting();
            MessageBox.Show(test);       
        }
        catch (Exception exc) 
        {
            MessageBox.Show(exc.ToString());
        }
    }

When I attempt to alter the Form, or call another method from here this is the error message I receive: "Cross Thead operation not valid".

I would like to be able to display the information elsewhere or even better yet place it into an array to later be stored as a file. Is there any way I can do this?

Thanks again!

You need to invoke on the main thread using Invoke or BeginInvoke :

public void OnReceived(object sender, SerialDataReceivedEventArgs c)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new EventHandler<SerialDataReceivedEventArgs>(OnReceived), sender, c);
        return;
    }

    com.DiscardOutBuffer();
    try
    {
        test = com.ReadExisting();
        MessageBox.Show(test);       
    }
    catch (Exception exc) 
    {
        MessageBox.Show(exc.ToString());
    }
}

Or you can factor out part of the event handler (like showing a message box) and invoke that instead.

The issue you have is that you are trying to update the UI from an non-ui thread. What you need to do is invoke your MessageBox call on the UI thread.

Something like:

public void OnReceived(object sender, SerialDataReceivedEventArgs c) // This is started in another thread...
{
    com.DiscardOutBuffer();
    try
    {
        test = com.ReadExisting();
        SetValue(test);       
    }
    catch (Exception exc) 
    {
        SetValue(exc.ToString());
    }
}


delegate void valueDelegate(string value);

private void SetValue(string value)
{   
    if (this.InvokeRequired)
    {
        this.Invoke(new valueDelegate(SetValue),value);
    }
    else
    {
        MessageBox.Show(value);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM