Delegate的Invoke、BeginInvoke,與控制元件的Invoke、BeginInvoke方法
阿新 • • 發佈:2018-12-22
轉自: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