解决多线程操作控件时可能出现的异常:“在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级”
.NET Framework 中关于“多线程 Windows 窗体控件示例”的一些摘要:
------------------------------------------------------
“Windows 窗体”使用单线程单元 (STA) 模型,因为“Windows 窗体”基于本机 Win32 窗口,而 Win32 窗口从本质上而言是单元线程。STA 模型意味着可以在任何线程上创建窗口,但窗口一旦创建后就不能切换线程,并且对它的所有函数调用都必须在其创建线程上发生。除了 Windows 窗体之外,.NET Framework 中的类使用自由线程模型。有关 .NET Framework 中的线程的信息,请参见线程处理。
STA 模型要求需从控件的非创建线程调用的控件上的任何方法必须被封送到(在其上执行)该控件的创建线程。基类 Control 为此目的提供了若干方法(Invoke、BeginInvoke 和 EndInvoke)。Invoke生成同步方法调用;BeginInvoke生成异步方法调用。
如果您在控件中为大量占用资源的任务使用多线程,则用户界面可以在背景线程上执行一个大量占用资源的计算的同时保持可响应。
------------------------------------------------------
线程安全更新控件的
使用步骤
1、定义更新控件专用的委托
2、定义与委托相应的更新控件的方法
3、声明更新控件的委托
4、定义线程更新控件的方法,在此方法中调用控件的Invoke或者BeginInvoke方法调用声明更新控件的委托
5、在线程中使用调用4中创建的方法
//1、定义更新控件专用的委托
private delegate void DGUpdateUI();
//2、定义与委托相应的更新控件的方法
private void UpdateUI()
{
try
{
MessageBox.Show("我试图通过线程更新控件!");
txtShowMessage.AppendText("我试图通过线程更新控件!");
MessageBox.Show("更新成功!");
}
catch (ExecutionEngineException ex)
{
MessageBox.Show("更新失败!错误是:" + ex.Message);
}
catch (Exception ex)
{
MessageBox.Show("更新失败!错误是:" + ex.Message);
}
}
//4、定义线程更新控件的方法
private void UpdateSuccess()
{
//3、声明更新控件的委托,当然也可以声明在外面
DGUpdateUI duu = new DGUpdateUI(UpdateUI);
txtShowMessage.Invoke(duu);
}
//5在线程中使用
private void btnSuccessHandler_Click(object sender, EventArgs e)
{
Thread thd = new Thread(new ThreadStart(UpdateSuccess));
thd.Start();
}
附上
最简单的方法:
方法一:需要定义个委托;
txtShowMessage.Invoke(new DGUpdateUI(delegate()
{
txtShowMessage.AppendText("线程完成!");
}));
方法二:呵呵,直接使用系统的ThreadStart委托就好啦....
txtShowMessage.Invoke(new ThreadStart(delegate()
{
txtShowMessage.AppendText("线程完成!");
}));