转载前,在网上找了好多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. 如何在spring容器开始后,和销毁前,执行一些操作

    转:参考文档:资料链接

  2. SQL DELETE 语句

    DELETE 语句用于删除表中的行. 语法 DELETE FROM 表名称 WHERE 列名称 = 值 Person: LastName FirstName Address City Gates Bi ...

  3. Alamofire 的使用

    最近,AFNetworking 的作者Mattt Thompson提交了一个新的类似于 AFNetworking 的网络 基础库,并且是专门使用最新的 Swift 语言来编写的,名为:Alamofir ...

  4. 点单登录原理和java实现简单的单点登录

    引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...

  5. asp.net 重定向的三种方法

    1.Server.Transfer("URL"): 服务器停止解析本页,保存此页转向前的数据后,再使页面转向到newPage.aspx, 并将转向前数据加上newPage.aspx ...

  6. oracle 常用函数【转】

    常用Oracle函数 SQL中的单记录函数 1.ASCII 返回与指定的字符对应的十进制数; SQL> select ascii('A') A,ascii('a') a,ascii('0') z ...

  7. selenium RC+JAVA 运行所遇到的问题

    1.报错一 Failed to start new browser session: java.lang.RuntimeException: Firefox 3 could not be found ...

  8. VS中使用svn注意事项

    1.程序需定期编译通过后上传SVN,每天可上传多次,根据个人程序开发进度决定,但每天晚下班前必须将当天的程序编译调试通过并上传SVN.每天早上上班首先需要更新SVN最新版本. 上传的工作流程应该是,更 ...

  9. LeetCode Add Two Numbers II

    原题链接在这里:https://leetcode.com/problems/add-two-numbers-ii/ 题目: You are given two linked lists represe ...

  10. LintCode Longest Common Subsequence

    原题链接在这里:http://www.lintcode.com/en/problem/longest-common-subsequence/ 题目: Given two strings, find t ...