My guess is that MyDataReceivedHandler
is running on a different thread than the GUI. In order to fix that, you need to invoke the Text
setters on the correct thread. This is a sample of doing so:
public void SetControlText(Control control, string text)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<Control,string>(SetControlText), new object[] { control, text });
}
else
{
control.Text = text;
}
}
private void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
//sp.PortName = "COM3";
//sp.Open();
SetControlText(Label1, sp.ReadLine());
}
catch (Exception exception)
{
SetControlText(RichTextBox1, exception.Message + "\n\n" + exception.Data);
}
finally
{
sp.Close();
}
}
If you are using .NET Framework 2.0, the above Action<T1, T2>
delegate is not available, so you will have to define your own one:
private delegate void SetControlTextHandler(Control control, string text);
public void SetControlText(Control control, string text)
{
if (this.InvokeRequired)
{
this.Invoke(new SetControlTextHandler(SetControlText), new object[] { control, text });
}
else
{
control.Text = text;
}
}
The SetControlText
method can be made shorter (and even static) like this (this works in both 2.0 and 3.5):
public static void SetControlText(Control control, string text)
{
´control.Invoke((MethodInvoker)delegate { control.Text = text; });
}
Then you don't need to do the check of InvokeRequired
each time, but you will on the other hand wrap the call in a delegate even if it is not needed. I think that in a GUI method like this any performance difference between those two is neglectible so I tend to use the shorter form, simply because it is less code to write.