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

时间:2011-03-29 04:53:12

标签: c# winforms serial-port multithreading

在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 个答案:

答案 0 :(得分:1)

在Main表单上使用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 :(得分:1)

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

答案 2 :(得分:1)

这只是因为Windows中的线程命令“你不能从任何其他线程访问UI但是UI线程”

因此,您需要使用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

相关问题