转载前,在网上找了好多INVOKE方法的文章,就这个看着还可以,明白了大概,以后再深用的时候再研究
,废话少说上转载(连转载都说的这么有气势,哈哈)
 
在设计界面时,我们经常需要将一些需要时间才能完成的操作放在另一个线程(不同于UI主线程)中执行。但是这些操作可能需要将其结果或完成情况通知主线程,比如调用窗体的方法,或者触发事件(由界面响应事件),很多情况下这种通知需要访问控件。
但是如果调用上述方法或者触发事件的线程不是控件的创建进程,Control就不能在创建它的thread之外被访问,此时会引发一个异常,好在可以通过控件的invoke方法来访问它。
Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的 Invoke 方法来将调用封送到适当的线程。
 
一、 Control.InvokeRequired 属性与 Invoke方法
 
Control.InvokeRequired 属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。MSDN中将其解释为“获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。
事实上,Control.InvokeRequired返回的结果就是 CurrentThread != ControlCreatThread 而已,在创建者线程和其它线程中,该值不同。
 
比较好的做法如下:
 
首先定义一个与可能被控件的非创建线程调用的方法或者事件处理函数的签名一样委托,如:
private  delegate  void  DeleUpdateText ( string  text );
 
当然直接使用已有的事件的委托也是可以的。
 
然后就是判断这个属性的值来决定是否要调用Invoke函数:
private  void  UpdateText ( string  text )
{
    if(this.InvokeRequired)
    {
        this.Invoke( new  DeleUpdateText( UpdateText ),  new  object[]{text} );
    }
    else
    {
        MyTextBox.Text   =  text;
    }
}
 
需要说明的:
1. Control.Invoke方法的第二个参数为 object[] 类型,作为指定方法的参数传递的对象数组。如果此方法没有参数,该参数可以是 null,或者使用不含该参数的重载版本。
2. 方法返回值的类型为 Object ,它包含正被调用的委托返回值;如果该委托没有返回值,则为 null。
 
二、BeginInvoke 方法
 
使用 Invoke 方法调用委托,在所委托的方法执行完成前,会阻塞进程,另一个更好的选择是异步调用委托的BeginInvoke方法,这个方法总是不等待委托的执行而立刻放回,特别适合于调用后就不用再管的方法执行。当然,也可以使用其返回的IAsyncResult类型的结果,并和委托的 EndInvoke 方法一起使用,以在该方法调用完毕后检索调用结果。
 
其参数和 Invoke 方法类似:
 
// Created on UI thread, but doesn't run on UI thread
private Label lblStatus;
{
    DoSomethingSlow();
    // Do UI update on UI thread
    object[] pList = { this, System.EventArgs.Empty };
    lblStatus.BeginInvoke( new System.EventHandler(UpdateUI), pList); }
    •••
    // Code to be run back on the UI thread
    // (using System.EventHandler signature, 
    // so we don't need to define a new delegate type here)
    private void UpdateUI(object o, System.EventArgs e)
    {
        // Now OK - this method will be called via Control.Invoke, 
        // so we are allowed to do things to the UI.
        lblStatus.Text = "Finished!";
    }
}
 
关于这个问题,发现了一篇讲解的特别清晰透彻的文章(作者:Ian Griffiths),附上原文和译文的名称和链接。似乎中英文版本的图片和代码都有些问题,在搜索引擎上直接搜索文章名或许可以找到排版更好的版本。
 
Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads
 
通过多线程为基于 .NET 的应用程序实现响应迅速的用户

[C#] Control.Invoke方法和跨线程访问控件(转载)的更多相关文章

  1. [C#] Control.Invoke方法和跨线程访问控件

    在设计界面时,我们经常需要将一些需要时间才能完成的操作放在另一个线程(不同于UI主线程)中执行.但是这些操作可能需要将其结果或完成情况通知主线程,比如调用窗体的方法,或者触发事件(由界面响应事件),很 ...

  2. C# WinFrom 跨线程访问控件

    1.跨线程访问控件委托和类的定义 using System; using System.Windows.Forms; namespace ahwildlife.Utils { /// <summ ...

  3. winform跨线程访问控件

    首先说下,.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.所以除了控件所在的线程外的线程调用会抛异常 (Cross-thread operation not va ...

  4. c#使用MethodInvoker解决跨线程访问控件

      功能函数测试集锦(77)  C#专区(114)  版权声明:本文为博主原创文章,未经博主允许不得转载. .net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线 ...

  5. C# 关于跨线程访问控件问题

    跨线程访问控件问题的原因是:控件都是在主线程中创建的,而系统默认控件的修改权归其创建线程所有.在子线程中如果需要直接修改控件的内容,需要使用委托机制将控件的修改操作交给主线程处理.因此,当没有使用委托 ...

  6. C# 跨线程访问控件(MethodInvoker)

    参考:https://www.cnblogs.com/lvdongjie/p/5428815.html .Net 通常禁止跨线程访问控件,设置Control.CheckForIllegalCrossT ...

  7. c#跨线程访问控件帮助类

    1.背景 对于winform程序来说,当我们点击按钮,需要消耗一定时长才能拿到数据后才能显示在界面上某个控件上的情况,我们通常会专门开一个线程去拿数据,这样不会造成界面处于假死状态 2.常规做法 // ...

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

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

  9. C#之Winform跨线程访问控件

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...

随机推荐

  1. Python强化训练笔记(七)——使用deque队列以及将对象保存为文件

    collections模块中的deque对象是一个队列,它有着正常队列的先进先出原则.我们可以利用这个对象来实现数据的保存功能. 例如,现有一个猜数字大小的游戏,系统开始会随机roll点一个0-100 ...

  2. C# 依赖注入

      http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 这篇文章真的非常非常好···绝对值得收藏学习.     目录 目录 1 ...

  3. 微信 {"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"}

    {"errcode":,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]" ...

  4. Socket练习

    第一类方法 package socketLianXi; import java.io.IOException; import java.io.InputStreamReader; import jav ...

  5. iOS应用程序的生命周期

    iOS应用程序一般都是由自己编写的代码和系统框架(system frameworks)组成,系统框架提供一些基本infrastructure给所有app来运行,而你提供自己编写的代码来定制app的外观 ...

  6. ORM系列之二:EF(1)

    目录 1. EF是什么 2. 如何获取EF 3. EF有哪些主要模式 EF是什么 EF全称为Entity Framework,是微软推荐的一种数据库访问技术,属于重量级的ORM框架,功能非常强大,目前 ...

  7. Python开发【第九章】:堡垒机实例

    一.堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作 模块安装 C:\Program Files\Python 3.5\Scri ...

  8. C学习笔记 知识集锦(二)

     1. 数组和指针 2. 字符串赋值 3. memset&memcpy 4. 机器数和真值,原码,反码和补码 5. 文件指针和文件描述符 6. 内存泄露和内存损坏 7. 什么是不可移植的程序 ...

  9. Vimium使用快捷键总结

    chrome 快捷键: ctrl+w 关闭当前标签  ctrl+t 新建标签 gg行首 shift+g 行尾 Vimium使用快捷键总结 j, <c-e> : Scroll down k, ...

  10. iOS 9后修改状态栏方法

    1.plist文件中添加View controller-based status bar appearance字段 值为NO 2.程序中添加 [UIApplication sharedApplicat ...