c# InvokeRequired和Invoke
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相关推荐
- InvokeRequired and Invoke
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.invokerequired(v=VS.90).aspx 在. ...
- c# winform InvokeRequired 解决跨线程访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它. Windows 窗体中 ...
- C# 多线程修改控件时遇到:创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke
一般在多线程调用UI控件时,涉及到跨线程修改UI,需要使用委托,比如如下: this.Invoke((MethodInvoker)delegate{btnRefresh.Enabled = true; ...
- C# async await 学习笔记2
C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html) 提到了ThreadId是一样的,突然想到在WinForm中,非UI线程 ...
- [转载]分享WCF聊天程序--WCFChat
http://www.cnblogs.com/gaoweipeng/archive/2009/09/04/1560260.html 无意中在一个国外的站点下到了一个利用WCF实现聊天的程序,作者是:N ...
- [转]WinForm下Splash(启动画面)制作
本文转自:http://www.smartgz.com/blog/Article/1088.asp 原文如下: 本代码可以依据主程序加载进度来显示Splash. static class Pr ...
- C#做的在线升级小程序
转自原文C#做的在线升级小程序 日前收到一个小任务,要做一个通用的在线升级程序.更新的内容包括一些dll或exe或.配置文件.升级的大致流程是这样的,从服务器获取一个更新的配置文件,经过核对后如有新的 ...
- c#中对Cross-thread operation not valid错误的处理办法
目录 目录 概要 1. Example 1.1 Unsafe access to control 1.2 What's mean? 2. The first choice : CheckForIlle ...
- C# 实现基于ffmpeg加虹软的人脸识别
2019独角兽企业重金招聘Python工程师标准>>> 关于人脸识别 目前的人脸识别已经相对成熟,有各种收费免费的商业方案和开源方案,其中OpenCV很早就支持了人脸识别,在我选择人 ...
最新文章
- android炫酷的自定义view,Android自定义View实现炫酷进度条
- Linux(64位)下OpenBabel 2.4.1、python2.7和Ipython实战(二)
- 编码区和非编码区的关系
- javacript实现不被浏览器拦截打开新窗口
- 在Windows下安装配置OpenCV-Python-PyCharm开发环境
- 随便贴两个漏洞,如 Apache JServ协议服务
- 媒体应用大数据,先解决三大难题
- arcgis创建剖面线execl文件
- javaBean和Servlet的区别
- 用了 HTTPS,没想到还是被监控了!
- appium-andriod自动化实现注意项
- 如何在Mac上快速签署PDF
- 每日一练蓝桥杯C语言:2020年真题题集(B组)
- matlab linux命令行窗口,linux命令行运行matlab
- 硕士论文latex参考文献格式经验
- 肿瘤浸润淋巴细胞的扩增方法学评估
- python简单实现排列和组合的计算
- win10自带sftp服务器_FreeSSHD在Windows环境下搭建SFTP服务器
- 关于Service抛出异常事务不回滚的原因和解决方法
- 操作系统面经总结—虚拟内存、内存分页、内存交换与覆盖等