I know the DataReceived event is fired on a background thread. How do I tell the GUI thread to show the data in the event handler?
You can use the IsInvokeRequired and BeginInvoke methods on your form to switch control back to the UI thread.
In some cases, I've also used a timer to watch for changes in some shared data structure like a list of messages. But that works best when you've got a pretty steady stream of messages coming from some background thread.
This code assumes you have already added a form-level SerialPort
object with the port_DataReceived
method attached to its DataReceived
event, and that you have a label named label1
on your form.
I'm not 100% certain about the code that converts the bytes available in the port to a string, as I have not run this with a live serial port collecting data. But this code will allow you to display the received data regardless of whether the event is on a different thread or not.
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
byte[] buffer = new byte[port.BytesToRead];
port.Read(buffer, 0, buffer.Length);
string data = UnicodeEncoding.ASCII.GetString(buffer);
if (label1.InvokeRequired)
{
Invoke(new EventHandler(DisplayData), data, EventArgs.Empty);
}
else
{
DisplayData(data, EventArgs.Empty);
}
}
private void DisplayData(object sender, EventArgs e)
{
string data = (string)sender;
label1.Text = data;
}