1. 程式人生 > >Delegate的Invoke、BeginInvoke,與控制元件的Invoke、BeginInvoke方法

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