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#BeginInvoke_和Invoke区别

  • 2011年12月07日 17:58
  • 103KB
  • 下载

C#窗体中Invoke和BeginInvoke方法详解

  • 2011年12月07日 17:59
  • 166KB
  • 下载

C#中Invoke 和 BeginInvoke 的区别

原文连接 相关资料:Invoke 和 BeginInvoke 的真正涵义 、在多线程中如何调用Winform Control.Invoke 方法 (Delegate) :在...

【转】C#窗体中Invoke和BeginInvoke方法详解(二)

二、消息机制---线程间和进程间通信机制 1、window消息发送 Windows消息机制是windows平台上的线程或者进程间通信机制之一。Windows消息值其实就是定义的一个数据结构,最重要...
  • doumin
  • doumin
  • 2011年11月07日 10:24
  • 331

C#中的Invoke和BeginInvoke方法详解

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

【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间的区别。所以花了点时间研究了下。   据msdn中介绍,它们最大的区别就是BeginInvoke属于异步执行的。 ...

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

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

C#中的invoke和begininvoke

原帖:http://www.cnblogs.com/Z-King/archive/2011/11/03/2234337.html 一直对invoke和begininvoke的使用和概念比较混乱,...

C#中用Invoke调用控件方法和BeginInvoke线程使用方法

C#中Invoke调用方法   在C#中,有时候会调用不同控件的同一个public(公共)方法,具体用到哪个控件的public方法却是视情况而定的,这个时候你就可以用Invoke了。   现在有控...

c# Invoke和BeginInvoke 区别

转自http://www.cnblogs.com/c2303191/articles/826571.htmlControl.Invoke 方法 (Delegate):在拥有此控件的基础窗口句柄的线程上...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# invoke和beginInvoke
举报原因:
原因补充:

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