首页 文章

“跨线程操作无效”..在串行端口上读取数据时

提问于
浏览
0

在Windows窗体应用程序中,在主窗体加载时,我设置了一个串口并开始读取它 . 目的是,当我在串口上收到一些数据时,我想打开另一个与数据相关的表格 .

所以我使用串口的DataReceived Event Handler .

void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

            string str = this.serialPort1.ReadLine();


                if (!string.IsNullOrEmpty(str))
                {


                    Main.Instance.customerData = new CustomerData(str);
                    Main.Instance.customerData.MdiParent = Main.Instance;  //Exeption received at this point
                    Main.Instance.customerData.Disposed += new EventHandler(customerData_Disposed);

                    Main.Instance.customerData.Show();


                }

        }

但是当我尝试在事件处理程序中打开一个表单时,它给了我一个InvalidOperationExeption,说:“跨线程操作无效:控制'Main'从其创建的线程以外的线程访问 . ”

我尝试删除代码行: Main.Instance.customerData.MdiParent = Main.Instance; 然后它工作正常 . 但它也必须分配mdiparent以便将其作为子窗体打开 .

有什么建议可以解决这个问题?

3 回答

  • 1

    在主窗体上使用Invoke方法 . 您必须将控制权传递给Main表单以与其进行交互 . 事件处理程序在后台线程上触发 .

    以下是一些可能有效的示例代码:

    void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string str = this.serialPort1.ReadLine();
        if (!string.IsNullOrEmpty(str))
        {
            ShowCustomerData(str);
        }   
    
    }
    
    private delegate void ShowCustomerDataDelegate(string s);
    
    private void ShowCustomerData(string s)
    {
        if (Main.Instance.InvokeRequired)
        {
            Main.Instance.Invoke(new ShowCustomerDataDelegate(ShowCustomerData), s);
        }
        else
        {
    
            Main.Instance.customerData = new CustomerData(str);
            Main.Instance.customerData.MdiParent = Main.Instance;  //Exeption received at this point
            Main.Instance.customerData.Disposed += new EventHandler(customerData_Disposed);
    
            Main.Instance.customerData.Show();
        }
    }
    
  • 1

    您的事件处理程序未在UI线程上运行 . 要获取UI线程,请使用主窗体的Invoke方法 .

  • 1

    这只是因为Windows中的线程命令是"Thou shalt not access UI from any other thread but the UI thread"

    因此,您需要使用Control.Invoke来运行在UI线程上访问UI的代码 .

    //assuming your within a control and using C# 3 onward..
    this.Invoke( () =>
     {
       //anything that UI goes here.
     }
    );
    

    一点点Stackoverflow Ninja Google Search本来可以帮到你的 . 这恰好是一个非常臭名昭着的问题 .

    这个答案似乎几乎就是你的问题:Cross-thread operation not valid while listening to a COM port

相关问题