尝试动态访问SerialPort时出现跨线程InvalidOperationException

时间:2013-06-04 12:26:25

标签: c# multithreading serial-port invalidoperationexception

我有多个串口设备连接到我的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.

这可能是什么陷阱?

1 个答案:

答案 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(); 
         }
     }