Invoke()的作用是:在应用程序的主线程上执行指定的委托。一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();

 
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。

正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。

(参考:http://lidunyang2008.blog.163.com/blog/static/190676205201322325426803/)
而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。
 

this.invoke()用法:

(1)

//修改按钮的Enabled属性

private void ModifyButton( bool _b )

{

this.Button1.Enabled = _b;

}

(2)

//声明上面方法的委托

private delegate void ModifyButton_dg( bool _b );

(3)

//调用委托

private void Calldelgate( )

{

/*在Windows窗体应用程序中使用this.Invoke    在WPF应用程序中使用this.Dispatcher.Invoke*/

this.Invoke( new ModifyButton_dg( ModifyButton ) ,new object[]{false});

}

(4)

可以在非UI线程中调用 ,如: 
      //创建线程

Thread _t = new Thread( new ThreadStart( threadmethod )); 
       _t.Start();

//线程入口

private void threadmethod () 
     { 
       //其他代码省略 
      Calldelgate(); 
     }

线程会在UI线程和辅助线程之间相互转换

例如:

举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个TextBox..

using System.Threading;

//启动一个线程 
Thread thread=new Thread(new ThreadStart(DoWork)); 
thread.Start();

//线程方法 
private void DoWork() 

this.TextBox1.Text="我是一个文本框";  /*在多线程中直接调用界面控件的方法是错误的做法*/

}

如果你像上面操作,在VS2005或2008里是会有异常的...

正确的做法是用Invoke\BeginInvoke

using System.Threading;
namespace test
{
  public partial class Form1 : Form
  {

public Form1()
  {
    InitializeComponent();
  }

①//更新窗体中的TextBox1显示内容的方法

public void UpdateForm(string param1,string parm2)
  {
    this.textBox1.Text = param1+parm2;
  }

②//声明委托

  public delegate void  UpdateForm_dl(string str1, string str2);

③//调用委托

private void Calldelegate()

{

/*在Windows窗体应用程序中使用this.Invoke    在WPF应用程序中使用this.Dispatcher.Invoke*/

this.BeginInvoke(new UpdateForm_dl(UpdateForm), new object[] { "我是文本框", "haha" });

//this.Dispatcher.BeginInvoke(new UpdateForm_dl(UpdateForm), new object[] { "我是文本框", "haha" });

}

④//创建新线程

private void button1_Click(object sender, EventArgs e)
  {
    Thread thread = new Thread(new ThreadStart(DoWork));
    thread.Start();
  }

⑤//新线程入口

public void DoWork()

{
     Calldelegate();
  }

}
}
注意代理的使用!

转载:C# this.Invoke()的作用与用法 理解三的更多相关文章

  1. C# this.Invoke()的作用与用法

    Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();   在多线程编程中,我们经常要在工作线程 ...

  2. C# this.Invoke()的作用和用法(摘)

    Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();   在多线程编程中,我们经常要在工作线程 ...

  3. (转载)MySQL数据类型中DECIMAL的作用和用法

    (转载)http://database.51cto.com/art/201005/201651.htm 在MySQL数据类型中,例如INT,FLOAT,DOUBLE,CHAR,DECIMAL等,它们都 ...

  4. Oracle分析函数及常用函数: over(),rank()over()作用及用法--分区(分组)求和& 不连续/连续排名

    (1)   函数:  over()的作用及用法:    -- 分区(分组)求和. sum() over( partition by column1 order by column2 )主要用来对某个字 ...

  5. og标签对SEO的作用及用法

    meta property=og标签对SEO的作用及用法,如果你仔细观察会发现本站点<head>代码中有一段:"property="og:image"这段代码 ...

  6. C++ "#"的作用和用法

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/48879093 1 #和##的作用和用法 ...

  7. serialVersionUID, ObjectInputStream与ObjectOutputStream类,Serializable接口,serialVersionUID的作用和用法

    ObjectInputStream与ObjectOutputStream类所读写的对象必须实现Serializable接口,对象中的transient和static类型成员变量不会被读取和写入 Ser ...

  8. Oracle函数over(),rank()over()作用及用法--分区(分组)求和& 不连续/连续排名

    (1)   函数:  over()的作用及用法:    -- 分区(分组)求和. RANK ( ) OVER ( [query_partition_clause] order_by_clause )D ...

  9. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

随机推荐

  1. hdu 4070 福州赛区网络赛J 贪心 ***

    优先发路程最长的 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...

  2. 遍历List过程中删除元素的正确做法(转)

    遍历List过程中删除元素的正确做法   public class ListRemoveTest {     3 public static void main(String[] args) { 4 ...

  3. android:layout_gravity和android:gravity属性的区别(转)

    gravity的中文意思就是”重心“,就是表示view横向和纵向的停靠位置 android:gravity:是对view控件本身来说的,是用来设置view本身的文本应该显示在view的什么位置,默认值 ...

  4. Linux crontab 定时任务详解

    1.每小时执行一次脚本 * */1 * * * /etc/init.d/smb restart #不是所有的系统都支持“*/1”这种写法可以试试: 0 * * * * /etc/init.d/smb  ...

  5. 【JavaScript基础学习】关于正则表达式的完整内容

    w3cJavaScript RegExp对象  这个如果第一次看的话应该会很莫名其妙,但可以看一遍留个印象. 正则表达式30分钟入门教程 这个教程非常完整,走一遍大概能够明白怎么回事了. 正则表达式在 ...

  6. Spring事务解析2-标签解析

    根据自定义标签的使用规则,可以知道会执行AnnotationDrivenBeanDefinitionParser的parse @Override public BeanDefinition parse ...

  7. 黑客语(Leet)

    黑客语(Leet)   Leet是从网络发展起来的一种文字书写方式.通常将英语中的字母替换为数字和特殊符号.这种方式被很多黑客组织所使用.由于具有隐密性,所以它也广泛被用于密码中.使用Leet书写的密 ...

  8. 关于JSP页面字段属性设为disabled或者readonly所带来的问题总结

    最近需要将页面一些自动求和的字段设为不可操作,当然disabled和readonly都可以实现,但是我的页面需求是来录入数据的,当用disabled时,该字段值是无法被获取并传到后台的,这时如果使用r ...

  9. Spring进阶—如何用Java代码实现邮件发送(二)

    http://www.cnblogs.com/itsource/p/4266905.html

  10. AC自动机+全概率+记忆化DP UVA 11468 Substring

    题目传送门 题意:训练指南P217 分析:没有模板串也就是在自动机上走L步,不走到val[u] == v的节点的概率 PS:边读边insert WA了,有毒啊! #include <bits/s ...