zoukankan      html  css  js  c++  java
  • C#Delegate.Invoke、Delegate.BeginInvoke And Control.Invoke、Control.BeginInvoke

    作者:EasonLeung

    一、Delegate的Invoke、BeginInvoke

    1、Delegate.Invoke (委托同步调用)

      a、委托的Invoke方法,在当前线程中执行委托。

      b、委托执行时阻塞当前线程,知道委托执行完毕,当前线程才继续向下执行。

      c、委托的Invoke方法,类似方法的常规调用。

    2、Delegate.BeginInvoke (委托异步调用)

      a、委托的BeginInvoke方法,在线程池分配的子线程中执行委托

      b、委托执行时不会阻塞主线程(调用委托的BeginInvoke线程),主线程继续向下执行。

      c、委托执行时会阻塞子线程。

      d、委托结束时,如果有返回值,子线程讲返回值传递给主线程;如果有回调函数,子线程将继续执行回调函数。

    3、Demo

      a、Delegate

     1         private void btn_General_Click(object sender, EventArgs e)
     2         {
     3             txt_Message.Text = "";
     4             txt_Message.Text += "主线程:"+ Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     5             //委托方法,在调用委托的线程中执行,本例中就是主线程(UI线程)。
     6             //执行一些耗时的操作,就会阻塞主线程(UI线程)
     7             //委托的普通调用就等于方法的直接调用,del();等价于SomeWork();
     8             del();
     9             //SomeWork();
    10             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    11         }

       b、Delegate.Invoke

    1         private void btn_Main_Invoke_Click(object sender, EventArgs e)
    2         {
    3             txt_Message.Text = "";
    4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
    5             //委托的同步调用,其实就是等价于委托的普通调用。
    6             del.Invoke();
    7             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    8         }
     1         private void btn_Sub_Invoke_Click(object sender, EventArgs e)
     2         {
     3             txt_Message.Text = "";
     4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     5 
     6             //开启新的线程执行委托,主线程(UI线程)继续向下执行
     7             new Thread(() => {
     8                 txt_Message.Text += "
    ----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     9                 //委托在调用线程中执行,并阻塞调用线程,知道委托方法执行结束。
    10                 del.Invoke();
    11                 txt_Message.Text += "
    ----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    12             }).Start();
    13 
    14             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    15         }

      c、Delegate.BeginInvoke

     1         private void btn_Main_BeginInvoke_Click(object sender, EventArgs e)
     2         {
     3             txt_Message.Text = "";
     4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     5             //委托异步调用
     6             //1、委托方法,在线程池中分配的子线程中执行。
     7             //2、主线程和子线程同时执行。
     8             //3、子线程结束之后,如果有返回值得话,将返回值传递给主线程。如果有回调函数的话,继续在子线程中执行回调函数。
     9 
    10             //有异常,控件不能在子线程中访问修改。
    11             //避免这类异常有两种方法   
    12             //1、手动关闭控件的跨线程安全检查Control.CheckForIllegalCrossThreadCalls = false;(不建议使用)
    13             //2、使用控件的Invoke方法。(推荐使用)
    14             del.BeginInvoke(null,null);
    15             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    16         }
     1         private void btn_Sub_BeginInvoke_Click(object sender, EventArgs e)
     2         {
     3             txt_Message.Text = "";
     4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     5 
     6             //开启新的线程执行委托,主线程(UI线程)继续向下执行
     7             new Thread(() =>
     8             {
     9                 txt_Message.Text += "
    ----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
    10                 //在线程池中分配的子线程中执行委托方法,调用委托的线程继续向下执行。
    11                 del.BeginInvoke(null, null); 
    12                 txt_Message.Text += "
    ----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    13             }).Start();
    14 
    15             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    16         }



    作者:EasonLeung

    二、Control的Invoke、BeginInvoke

    1、Control.Invoke (同步调用)  

      (1)在主线程(UI线程)中调用Control.Invoke

        a、在主线程(UI线程)中调用Control.Invoke,先执行Invoke的方法,再执行Invoke后面的代码。

      (2)在子线程中调用Control.Invoke

        a、子线程中调用Control.Invoke,子线程将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。 主线程继续向下执行,子线程处于阻塞状态。

        b、当该消息被主线程执行完成后,子线程才能继续往下执行。

    2、Delegate.BeginInvoke (异步调用)

      (1)在主线程(UI线程)中调用Control.BeginInvoke

        a、在主线程(UI线程)中调用Control.BeginInvoke,将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。先执行Invoke后面的代码,再执行Invoke的方法。

      (2)在子线程中调用Control.BeginInvoke

        a、子线程中调用Control.BeginInvoke,子线程将调用的方法封装成消息,调用API的RegisterWindowMessage()向UI窗口发送消息。主线程继续向下执行,子线程也继续向下执行。

        b、最后由主线程执行Invoke的方法

    3、Demo

      a、在主线程(UI线程)中调用Control.Invoke

     1         private void btn_Main_Invoke_Click(object sender, EventArgs e)
     2         {
     3             //执行顺序:代码A -> 代码Invoke -> 代码B
     4             //都是在主线程中执行
     5 
     6             txt_Message.Text = "";
     7             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     8             //代码A
     9             this.txt_Message.Invoke(del);
    10             //代码B
    11             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    12         }

      b、在子线程中调用Control.Invoke

     1         private void btn_Sub_Invoke_Click(object sender, EventArgs e)
     2         {
     3             //执行顺序:
     4             //1、代码A(主线程执行)
     5             //2、代码D(主线程执行) 和 代码B(子线程执行) 并发执行
     6             //3、封装消息,并在UI线程中注册消息(子线程执行)
     7             //4、代码Invoke(主线程执行)
     8             //5、代码C(子线程执行)
     9 
    10             txt_Message.Text = "";
    11             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
    12             //代码A
    13             new Thread(() =>
    14             {
    15                 //代码B
    16                 int temp = 0;
    17                 this.txt_Message.Invoke(del);
    18                 //代码C
    19                 temp = 1;
    20             }).Start();
    21             //代码D
    22             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    23         }

      c、在主线程(UI线程)中调用Control.BeginInvoke

     1         private void btn_Main_BeginInvoke_Click(object sender, EventArgs e)
     2         {
     3             //执行顺序:代码A -> 封装消息,并在UI线程中注册消息 -> 代码B -> 代码Invoke
     4             //都是在主线程中执行
     5 
     6             txt_Message.Text = "";
     7             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
     8             //代码A
     9             this.txt_Message.BeginInvoke(del);
    10             //代码B
    11             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    12         }

      c、在子线程中调用Control.BeginInvoke

     1         private void btn_Sub_BeginInvoke_Click(object sender, EventArgs e)
     2         {            
     3             //执行顺序:
     4             //1、代码A(主线程执行)
     5             //2、代码D(主线程执行) 和 代码B(子线程执行) 并发执行
     6             //3、封装消息,并在UI线程中注册消息(子线程执行)
     7             //4、代码C(子线程执行)
     8             //5、代码Invoke(主线程执行)
     9 
    10             txt_Message.Text = "";
    11             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作
    ";
    12             //代码A
    13             new Thread(() =>
    14             {
    15                 //代码B
    16                 int temp = 0;
    17                 this.txt_Message.BeginInvoke(del);
    18                 //代码C
    19                 temp = 1;
    20             }).Start();
    21             //代码D
    22             txt_Message.Text += "
    主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束
    ";
    23         }

    代码下载

  • 相关阅读:
    HDU 1075 What Are You Talking About(字典树)
    HDU 1075 What Are You Talking About (stl之map映射)
    HDU 1247 Hat’s Words(字典树活用)
    字典树HihoCoder
    HDU 1277全文检索(字典树)
    HDU 3294 Girls' research(manachar模板题)
    HDU 3294 Girls' research(manachar模板题)
    HDU 4763 Theme Section(KMP灵活应用)
    Ordering Tasks UVA
    Abbott's Revenge UVA
  • 原文地址:https://www.cnblogs.com/EasonLeung/p/3683492.html
Copyright © 2011-2022 走看看