在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以便将其作为子表格打开。
有任何解决此问题的建议吗?
答案 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