Reputation: 818
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!
Upvotes: 0
Views: 157
Reputation: 3717
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);
}
}
Upvotes: 1
Reputation:
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.
Upvotes: 1