我有多个串口设备连接到我的PC,我正在开发一个程序,允许用户选择他们想要的端口,然后程序将动态创建TabPage
并将它们添加到TabControl
。
每个标签页还会有一个多行TextBox
,它会显示从指定的序列端口传入的数据。
以下是我的代码,它试图动态创建这些控件:
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
};
}
问题: 以下是我在运行时遇到的错误,并在第87行(在上面的代码上发表评论)中解决:
Cross-thread operation not valid: Control 'COM16' accessed from a thread other than the thread it was created on.
这可能是什么陷阱?
答案 0 :(得分:1)
您正在接收后台线程的数据,并尝试从非UI线程更新UI。您需要将后台线程中的数据封送到UI线程以更新控件。这可以使用Control.Invoke方法完成。
sp.DataReceived += delegate
{
if (tb.InvokeRequired)
{
tb.Invoke(new Action(() =>
{
tb.Text += sp.ReadExisting();
}));
}
else
{
tb.Text += sp.ReadExisting();
}
}