ialPort时发生跨线程InvalidOperationExc

ialPort时发生跨线程InvalidOperationExc

本文介绍了尝试动态访问SerialPort时发生跨线程InvalidOperationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个连接到PC的串行设备,并且正在开发一个程序,该程序允许用户选择所需的任意多个端口,然后该程序将动态创建TabPage并将其添加到TabControl.

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.

每个选项卡页面上还将有一个多行TextBox,该行将显示从分配的串行端口到该端口的传入数据.

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
                        };
}

问题:这是我在运行时遇到的错误,并中断了第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?

推荐答案

您正在接收后台线程上的数据,并尝试从非UI线程更新UI.您需要将数据从后台线程封送至UI线程,以更新控件.可以使用 Control.Invoke 方法来完成.

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

这篇关于尝试动态访问SerialPort时发生跨线程InvalidOperationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 22:19