C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它。此时它将会在内部调用new MethodInvoker(LoadGlobalImage)来完成下面的步骤,这个做法保证了控件的安全,你可以这样理解,有人想找你借钱,他可以直接在你的钱包中拿,这样太不安全,因此必须让别人先要告诉你,你再从自己的钱包把钱拿出来借给别人,这样就安全了

------------------------------------------------------------------------

在设计中为了让界面与逻辑分离,我的做法是使用事件,界面只要响应事件来处理界面的显示就行了。而事件在逻辑处理中可能由不同的线程引发,这些事件的响应方法在修改界面中的控件内容时便会引发一个异常。

这时就用到了Control.InvokeRequired 属性 与Invoke方法。

------------------------------------------------------------------------

获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。

如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。

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

------------------------------------------------------------------------

首先定义一个委托,与这个事件处理函数的签名一样委托,当然直接使用该事件的委托也是可以的,如:

 private   delegate   void  InvokeCallback( string  msg);

然后就是判断这个属性的值来决定是否要调用Invoke函数:

 void  m_comm_MessageEvent( string  msg){if (txtMessage.InvokeRequired){InvokeCallbackmsgCallback  =   new  InvokeCallback(m_comm_MessageEvent);txtMessage.Invoke(msgCallback,  new   object []  { msg } );} else {txtMessage.Text  =  msg;} }

说明:这个函数就是事件处理函数,txtMessage是一个文本框。

这样就做到了窗体中控件的线程安全性。

------------------------------------------------------------------------

InvokeRequired 当前线程不是创建控件的线程时为true

比如你可以自己开一个Thread,或使用Timer的事件来访问窗体上的控件的时候,在线程中窗体的这个属性就是True的。

简单的说,如果有两个线程,Thread A和Thread B,并且有一个Control c,是在Thread A里面new的。

那么在Thread A里面运行的任何方法调用c.InvokeRequired都会返回false。

相反,如果在Thread B里面运行的任何方法调用c.InvokeRequired都会返回true。

是否是UI线程与结果无关。(通常Control所在的线程是UI线程,但是可以有例外)

也可以认为,在new Control()的时候,control用一个变量记录下了当前线程,在调用InvokeRequired时,返回当前线程是否不等于new的时候记录下来的那个线程。

c# InvokeRequired和Invoke相关推荐

  1. InvokeRequired and Invoke

    http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.invokerequired(v=VS.90).aspx 在. ...

  2. c# winform InvokeRequired 解决跨线程访问控件

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它. Windows 窗体中 ...

  3. C# 多线程修改控件时遇到:创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke

    一般在多线程调用UI控件时,涉及到跨线程修改UI,需要使用委托,比如如下: this.Invoke((MethodInvoker)delegate{btnRefresh.Enabled = true; ...

  4. C# async await 学习笔记2

    C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html) 提到了ThreadId是一样的,突然想到在WinForm中,非UI线程 ...

  5. [转载]分享WCF聊天程序--WCFChat

    http://www.cnblogs.com/gaoweipeng/archive/2009/09/04/1560260.html 无意中在一个国外的站点下到了一个利用WCF实现聊天的程序,作者是:N ...

  6. [转]WinForm下Splash(启动画面)制作

    本文转自:http://www.smartgz.com/blog/Article/1088.asp 原文如下: 本代码可以依据主程序加载进度来显示Splash.     static class Pr ...

  7. C#做的在线升级小程序

    转自原文C#做的在线升级小程序 日前收到一个小任务,要做一个通用的在线升级程序.更新的内容包括一些dll或exe或.配置文件.升级的大致流程是这样的,从服务器获取一个更新的配置文件,经过核对后如有新的 ...

  8. c#中对Cross-thread operation not valid错误的处理办法

    目录 目录 概要 1. Example 1.1 Unsafe access to control 1.2 What's mean? 2. The first choice : CheckForIlle ...

  9. C# 实现基于ffmpeg加虹软的人脸识别

    2019独角兽企业重金招聘Python工程师标准>>> 关于人脸识别 目前的人脸识别已经相对成熟,有各种收费免费的商业方案和开源方案,其中OpenCV很早就支持了人脸识别,在我选择人 ...

最新文章

  1. android炫酷的自定义view,Android自定义View实现炫酷进度条
  2. Linux(64位)下OpenBabel 2.4.1、python2.7和Ipython实战(二)
  3. 编码区和非编码区的关系
  4. javacript实现不被浏览器拦截打开新窗口
  5. 在Windows下安装配置OpenCV-Python-PyCharm开发环境
  6. 随便贴两个漏洞,如 Apache JServ协议服务
  7. 媒体应用大数据,先解决三大难题
  8. arcgis创建剖面线execl文件
  9. javaBean和Servlet的区别
  10. 用了 HTTPS,没想到还是被监控了!
  11. appium-andriod自动化实现注意项
  12. 如何在Mac上快速签署PDF
  13. 每日一练蓝桥杯C语言:2020年真题题集(B组)
  14. matlab linux命令行窗口,linux命令行运行matlab
  15. 硕士论文latex参考文献格式经验
  16. 肿瘤浸润淋巴细胞的扩增方法学评估
  17. python简单实现排列和组合的计算
  18. win10自带sftp服务器_FreeSSHD在Windows环境下搭建SFTP服务器
  19. 关于Service抛出异常事务不回滚的原因和解决方法
  20. 操作系统面经总结—虚拟内存、内存分页、内存交换与覆盖等

热门文章

  1. 应用层——HTTP协议
  2. ChainStore:浅谈DApp区块链游戏的现状
  3. Java 中的 getResource 方法
  4. springboot启动时,排除某些自动配置类
  5. edu邮箱怎么申请一个1T的onedrive
  6. 什么是MEID号如何申请MEID,A0、A1、A2以及99开头的MEID号的区别?
  7. 字符数组 - 数组名
  8. 什么叫显示动力学,什么叫隐式动力学分析!
  9. Java String intern()方法
  10. MemSQL、SQLFire、Oracle XE性能对比测试