Invoke BeginInvoke

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Invoke BeginInvoke相关的知识,希望对你有一定的参考价值。

首先说下,invoke和begininvoke的使用有两种情况:

  1. control中的invoke、begininvoke。(控件)

  2. delegrate中的invoke、begininvoke。(委托)  

  这两种情况是不同的,我们这里要讲的是第1种。下面我们在来说下.NET中对invoke和begininvoke的官方定义。

  control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。

  control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。

  根据这两个概念我们大致理解invoke表是同步、begininvoke表示异步。但是如何来进行同步和异步呢?我们来做一个测试。

invoke 例子:

 private void button1_Click(object sender, EventArgs e)
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
            invokeThread = new Thread(new ThreadStart(StartMethod));
            invokeThread.Start();
            string a = string.Empty;
            for (int i = 0; i < 3; i++)      //调整循环次数,看的会更清楚
            {
                Thread.Sleep(1000);   
                a = a + "B";
            }
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}

 private void StartMethod()
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
            button1.Invoke(new invokeDelegate(invokeMethod));  
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}

 private void invokeMethod()
{
            //Thread.Sleep(3000);
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEE");

结论:我们运行后,看下程序的运行顺序,1AAA->3CCC和1BBB->1EEE ->3DDD 。 

解释:主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过invoke来将invokemethod方法提交给主线程,然后子线程等待主线程执行,直到主线程将invokemethod方法执行完成(期间必须等待主线程的任务执行完成,才会去执行invoke提交的任务),最后执行子线程3DDD。(子线程在此处等待,等待invoke的委托执行完成

 

begininvoke 例子:

private void button1_Click(object sender, EventArgs e)
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"AAA");
            invokeThread = new Thread(new ThreadStart(StartMethod));
            invokeThread.Start();
            string a = string.Empty;
            for (int i = 0; i < 3; i++)      //调整循环次数,看的会更清楚
            {
                Thread.Sleep(1000);   
                a = a + "B";
            }
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+a);
}

 private void StartMethod()
{
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"CCC");
            button1.BeginInvoke(new invokeDelegate(invokeMethod));  
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString()+"DDD");
}

 private void beginInvokeMethod()
        {
            //Thread.Sleep(3000);
            MessageBox.Show(Thread.CurrentThread.GetHashCode().ToString() + "EEEEEEEEEEEE");
        }

 

结论: 我们运行后看看执行的结果:1AAA->1BBB和3CCC->1EEE和3DDD。

解释: 主线程运行1AAA,然后1BBB和子线程3CCC同时执行,然后通过begininvoke来将invokemethod方法提交给主线程,然后主线程执行1EEE(主线程自己的任务执行完成), 同时子线程继续执行3DDD。(子线程与主线程同步执行,子线程不等待

 

 

Control的Invoke与BeginInvoke所执行的委托都是又控件所在的线程执行的;;;异步同步是针对子线程----通过以上的解释可得。

以上是关于Invoke BeginInvoke的主要内容,如果未能解决你的问题,请参考以下文章

invoke和begininvoke 区别

C#中的invoke和begininvoke

Invoke 与 BeginInvoke的区别

C#中Control的Invoke和BeginInvoke是相对于支线线程

Control.Invoke() 与 Control.BeginInvoke() [重复]

C# 多线程 Invoke BeginInvoke