问题
I have multiple serial devices connected to my PC and I am working on a program that allows users select as many as ports they want and then the program will dynamically creates TabPage
and adds them to TabControl
.
Each tab page will also have a multiline TextBox
that will show the incoming data from the assigned serialport to it.
Here is my code that tries to create these controls dynamically:
private void AddSerialPort(string portName)
{
ActiveSerialPorts.Add(portName);
if (!tabControlActiveSerialPorts.Enabled)
tabControlActiveSerialPorts.Enabled = true;
var page = new TabPage(portName);
page.Text = portName;
var tb = new TextBox();
tb.Name = portName;
tb.Dock = DockStyle.Fill;
tb.BackColor = Color.Black;
tb.Multiline = true;
page.Controls.Add(tb);
tabControlActiveSerialPorts.TabPages.Add(page);
var sp = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
sp.Open();
tb.Tag = sp;
sp.DataReceived += delegate
{
tb.Text += sp.ReadExisting(); //LINE 87
};
}
PROBLEM: Here is the error I get on runtime, and break lands on line 87 (commented on code above):
Cross-thread operation not valid: Control 'COM16' accessed from a thread other than the thread it was created on.
What could be the possible pitfall here?
回答1:
You're receiving data on background thread and trying to update the UI from the non-UI thread. You need to marshal the data from the background thread to the UI thread in order to update the control. This can be done using the Control.Invoke method.
sp.DataReceived += delegate
{
if (tb.InvokeRequired)
{
tb.Invoke(new Action(() =>
{
tb.Text += sp.ReadExisting();
}));
}
else
{
tb.Text += sp.ReadExisting();
}
}
来源:https://stackoverflow.com/questions/16917810/cross-thread-invalidoperationexception-while-trying-to-access-serialport-dynamic