Delegate的Invoke、BeginInvoke,与控件的Invoke、BeginInvoke方法

转自:https://www.cnblogs.com/EasonLeung/p/3683492.html

一、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 + "---开始工作\r\n";
 5             //委托方法,在调用委托的线程中执行,本例中就是主线程(UI线程)。
 6             //执行一些耗时的操作,就会阻塞主线程(UI线程)
 7             //委托的普通调用就等于方法的直接调用,del();等价于SomeWork();
 8             del();
 9             //SomeWork();
10             txt_Message.Text += "\r\n主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
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 + "---开始工作\r\n";
5             //委托的同步调用,其实就是等价于委托的普通调用。
6             del.Invoke();
7             txt_Message.Text += "\r\n主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
8         }

复制代码

复制代码

 1         private void btn_Sub_Invoke_Click(object sender, EventArgs e)
 2         {
 3             txt_Message.Text = "";
 4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作\r\n";
 5 
 6             //开启新的线程执行委托,主线程(UI线程)继续向下执行
 7             new Thread(() => {
 8                 txt_Message.Text += "\r\n----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作\r\n";
 9                 //委托在调用线程中执行,并阻塞调用线程,知道委托方法执行结束。
10                 del.Invoke();
11                 txt_Message.Text += "\r\n----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
12             }).Start();
13 
14             txt_Message.Text += "\r\n主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
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 + "---开始工作\r\n";
 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 += "\r\n主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
16         }

复制代码

复制代码

 1         private void btn_Sub_BeginInvoke_Click(object sender, EventArgs e)
 2         {
 3             txt_Message.Text = "";
 4             txt_Message.Text += "主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作\r\n";
 5 
 6             //开启新的线程执行委托,主线程(UI线程)继续向下执行
 7             new Thread(() =>
 8             {
 9                 txt_Message.Text += "\r\n----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始工作\r\n";
10                 //在线程池中分配的子线程中执行委托方法,调用委托的线程继续向下执行。
11                 del.BeginInvoke(null, null); 
12                 txt_Message.Text += "\r\n----子线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
13             }).Start();
14 
15             txt_Message.Text += "\r\n主线程:" + Thread.CurrentThread.ManagedThreadId + "---开始结束\r\n";
16         }

复制代码

二、Control的Invoke、BeginInvoke

在主线程和子线程中执行的方式 https://blog.csdn.net/allenjy123/article/details/7232321?utm_source=blogxgwz0

  




猜你喜欢

转载自blog.csdn.net/u013986317/article/details/80919662