问题:
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,它会出现以下错误:
“线程间操作无效: 从不是创建控件“X”的线程访问它。”
解决方法:
Control.InvokeRequired 属性和Invoke方法 或 BeginInvoke方法就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。
关于Control.InvokeRequired 属性,MSDN中写:
Control.InvokeRequired Property
获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
属性值
Boolean
如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。
注解
Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性 。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。
Invoke方法 和 BeginInvoke方法的区别:
control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。
一般的做法是定义委托,通过 Invoke 或者 BeginInvoke 去调用,两者

在多线程环境中,直接在工作线程中修改UI控件会导致线程间操作错误。C#提供了Control.InvokeRequired属性和Invoke/BeginInvoke方法来解决这一问题。InvokeRequired检查是否需要调用Invoke以在正确线程中执行操作,而Invoke是同步调用,BeginInvoke则是异步的。在WPF中,可以使用Dispatcher属性和CheckAccess方法来实现线程安全的控件访问。
最低0.47元/天 解锁文章
662





