C# invoke和beginInvoke

原创 2015年11月18日 09:58:45

UI线程以外的线程不能直接更新UI界面,那如何在工作线程中更新UI界面呢?


invoke和beginInvoke的出现是为了解决跨线程更新UI显示的问题,invoke是同步的执行,而beginInvoke是异步执行的,不会阻塞后面的代码,但如果使用了endInvoke监听的话同样会阻塞后面代码,此时的作用相当于invoke。


此处以一个10秒走表例子来说明问题


一、阻塞UI线程方法

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 1; i <=10;i++)
            {
                 Thread.Sleep(1000);
                 lblSecond.Text = i.ToString();//主线程会卡死
            }
        }


二、创建新线程执行任务,并用control.Invoke更新UI显示

        private void button2_Click(object sender, EventArgs e)
        {
            Thread myThread = new Thread(new ThreadStart(ShowSecond));
            myThread.Start();
        }

        private delegate void showSecondDelegate();//定义一个委托

        private void ShowSecond()
        {
            for (int i = 1; i <= 10; i++)
            {
                Thread.Sleep(1000);
                this.Invoke(new showSecondDelegate(delegate() //在委托方法中更新UI控件值
                {
                    lblSecond.Text = i.ToString(); //如果将thread.sleep放到此处,则会阻塞主线程,因为此处运行在主线程上
                }));
                //后面的代码    //后面的代码会等invoke委托方法执行完成后再执行
                //...
             }
        }

三、创建新线程执行任务,并用control.BeginInvoke更新UI显示

        private void button3_Click(object sender, EventArgs e)
        {
            Thread myThread = new Thread(ShowSecond1);
            myThread.Start();
        }

        private delegate void showSecondDelegate1(); 
        private void ShowSecond1()
        {
            for (int i = 1; i <= 10; i++)
            {

                this.BeginInvoke(new showSecondDelegate1(delegate()
                {
                    MessageBox.Show(i.ToString());
                    lblSecond.Text = i.ToString();
                }));
                //后面的代码     //后面的代码会立即执行,不会等BeginInvoke委托方法执行完成后再执行
                //...                               
            }            
        }

四、创建新线程执行任务,并用control.BeginInvoke更新UI显示,使用control.EndInvoke监听结果,并阻塞当前线程
       private delegate bool showSecondDelegate2(); 
        /// <summary>
        /// 异步(beginInvoke更新UI-阻塞工作线程)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            Thread myThread = new Thread(ShowSecond2);
            myThread.Start();
            
        }

        private void ShowSecond2()
        {
            for (int i = 1; i <= 10; i++)
            {
                Thread.Sleep(1000);
                IAsyncResult iasync = this.BeginInvoke(new showSecondDelegate2(delegate()
                {
                    lblSecond.Text = i.ToString();
                    return true;
                }));
                object result = this.EndInvoke(iasync);  //监听BeginInvoke委托方法执行结果,阻塞后面代码执行,直到委托方法执行完成               
                //后面的代码
                //...
        }    }



总结:


1、invoke和beginInvoke委托方法依然运行在主线程中,而不是当前线程,使用thread.sleep照样会阻塞主线程,所以耗时的操作应该放在工作线程中执行,更新UI显示

      相关的代码放在委托方法中

2、在工作线程中想异步更新UI界面显示的话用beginInvoke,不影响后面代码运行

C#中的Invoke和BeginInvoke方法详解

在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法。   一、为什么Control类提供了Invoke和...
  • startwithdp
  • startwithdp
  • 2015年03月19日 18:23
  • 3426

C# Control的Invoke和BeginInvoke及其实现机制(消息循环)

与C++不同,C#语言禁止在创建某个控件的线程外对控件进行访问,否则会引起访问违规的异常。但有些时候,我们的确需要从其他线程对控件,此时就需要借助于Invoke和BeginInvoke之手了。我们先来...
  • Baple
  • Baple
  • 2014年03月19日 13:35
  • 5471

C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法

1.C#中的每一个委托都内置了BeginInvoke和EndInvoke方法,如果委托的方法列表里只有一个方法,那么这个方法就可以异步执行(不在当前线程里执行,另开辟一个线程执行)。委托的BeginI...
  • xuanwuziyou
  • xuanwuziyou
  • 2014年12月04日 15:38
  • 4826

C#中Invoke 和 BeginInvoke 的区别(多线程调用Winform)

今天师弟问我SuperGridControl的线程安全问题,我查了一下资料,不知道下面方法是否能解决,但是感觉这个函数很不错,记下来以后试试。 原文连接 相关资料:Invoke 和 B...
  • u011447369
  • u011447369
  • 2015年03月18日 20:53
  • 2008

委托的invoke、beginInvoke和控件的invoke、beginInvoke的区别

原文地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html  在Invoke或者BeginInvoke的使用中无...
  • ydm19891101
  • ydm19891101
  • 2015年11月27日 14:01
  • 2891

C# 用委托BeginInvoke做异步线程

一个应用场景,浏览器上传一个文件,此文件后台调用文件转换,需要耗费相当长的时间,这样,如果是一个线程同步式的做下去,那么用户在浏览器上感觉就是卡住了,卡卡卡卡,这里我们利用委托的BeginInvoke...
  • chenqiangdage
  • chenqiangdage
  • 2015年11月18日 17:48
  • 2198

"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke"

文章出处:http://www.cnblogs.com/hsapphire/archive/2010/10/21/1857421.html 哎,有接近半年的时候没有真正的写c#程序了,这段时...
  • Banket004
  • Banket004
  • 2013年03月26日 15:32
  • 2993

理解串行并行、同步异步与invoke、begininvoke和endinvoke的关系

首先这是我自己理解的结果,后面随着学习的深入发现问题的话我会再回来改。 串行和并行给我的感觉更多的是方法上的执行顺序 同步与异步给我更多的感觉是线程中的执行顺序,在这里我之前也遇到了一个误区,认为...
  • u014231459
  • u014231459
  • 2017年02月03日 10:38
  • 586

异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)

http://www.cnblogs.com/panjun-Donet/archive/2009/03/03/1284700.html 让我们来看看同步异步的区别: 同步方法调用在程序继续执行之前...
  • OnafioO
  • OnafioO
  • 2015年03月17日 22:12
  • 1615

C#中的线程二(BeginInvoke和Invoke)

C#中invoke的相关资料,转载自http://www.codeceo.com/article/csharp-thread-2.html,讲的比较细 近日,被Control的Invoke和Be...
  • lcydhr
  • lcydhr
  • 2015年12月25日 10:05
  • 308
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# invoke和beginInvoke
举报原因:
原因补充:

(最多只允许输入30个字)