from:http://www.th7.cn/Program/net/201306/140033.shtml

Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。

如果已经创建控件的句柄,则除了 InvokeRequired 属性以外,控件上还有四个可以从任何线程上安全调 用的方法,它们是: Invoke、 BeginInvoke、 EndInvoke 和 CreateGraphics。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,当从另一个线程进行调用时,应使用这些 Invoke 方法之一。

如果控件句柄尚不存在,则 InvokeRequired 沿控件的父级链搜索,直到它找到有窗口句柄的控件或窗体为止。 如果找不到合适的句柄, InvokeRequired 方法将返回 false。

这意味着如果不需要 Invoke(调用发生在同一线程上),或者如果控件是在另一个线程上创建的但尚未创建控件的句柄,则 InvokeRequired 可以返回 false。

如果尚未创建控件的句柄,您就不能简单地在控件上调用属性、方法或事件。这可能导致在后台线程上创建控件的句柄,从而隔离不带消息泵的线程上的控件并使应用程序不稳定。

当 InvokeRequired 在后台线程上返回 false 时,您也可以通过检查 IsHandleCreated 的值来避免这种情况。 如果尚未创建控件句柄,您必须等到控件句柄已创建,才能调用 Invoke 或 BeginInvoke。 通常,仅当在应用程序主窗体的构造函数中创建了后台线程时(如同在 Application.Run(new MainForm()) 中),在已经显示窗体或取消 Application.Run 之前,才会发生这种情况。

一种解决方案是等到已经创建了窗体的句柄,然后启动后台线程。通过调用 Handle 属性强制创建句柄,或者等待 Load 事件启动后台进程。

一种更好的解决方案是使用 SynchronizationContext 返回的 SynchronizationContext,而不是使用控件进行线程间封送处理。——MSDN

关于这方面一个更容易的解释以及例子(参考链接:关于invokeRequired与invoke):

而关于InvokeRequired与Invoke是个老生常谈的问题,一般标准写法为(图片截图来自:Avoiding InvokeRequired,下同):

这种方式的好处就是能在.NET 1.0+上正常运行,但是如果存在很多控件的话,就会存在这样很多代码(大量定义委托)。

而在.NET 2.0上,可以采用匿名委托和MethodInvoker,简化代码写法,关于MethodInvokerMSDN上的定义如下:

MethodInvoker 提供一个简单委托,该委托用于调用含 void 参数列表的方法。 在对控件的 Invoke 方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。

或者更简洁的写法:

而在.NET 3.5+可以利用其特性,代码如下(截图来在:A Generic Method for Cross-thread Winforms Access

参考资料:

关于invokeRequired与invoke

Avoiding InvokeRequired

A Generic Method for Cross-thread Winforms Access

最新文章

  1. 大熊君大话NodeJS之------MongoDB模块(额外篇)
  2. 如果因特网中的所有链路都提供可靠的交付服务,TCP可靠传输服务是多余的吗?
  3. [转载]TFS安装配置教程
  4. 常用JS效果 不断进步贴 不停更新~ 纪念用~
  5. 【BZOJ】1105: [POI2007]石头花园SKA
  6. 黑马程序员——OC语言 核心语法 (3)
  7. web安全之sql注入实例(5.0之前的)
  8. 解决TIME_WAIT过多造成的问题
  9. 集成代码编辑器ACE的经验
  10. Memcached基础
  11. QT在Windows控制台下输出
  12. Python中模块之sys的功能介绍
  13. linux device drivers ch02
  14. BZOJ1030 [JSOI2007]文本生成器 AC自动机 动态规划
  15. codeM编程大赛E题 (暴力+字符串匹配(kmp))
  16. .NET在IE10下的回传BUG修复
  17. INNODB存储引擎表空间
  18. Tensorflow源码编译,解决tf提示未使用SSE4.1 SSE4.2 AVX警告【转】
  19. dp之多重背包poj2392
  20. Oracle 使用序列、触发器实现自增

热门文章

  1. Visual Studio Productivity Power Tools居然也开源
  2. Oracle 第一天
  3. Hdu 4081 最小生成树
  4. iOS typedef NS_ENUM 与 NSString
  5. iOS 遍历AutoLayout约束
  6. js学习
  7. PHP+MySQL+Easyui tree菜单从后台加载json数据(一)
  8. Shader实例:边缘发光和描边
  9. db2 import export load
  10. c#使用多线程的几种方式示例详解