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 }
文章轉載自:https://www.cnblogs.com/EasonLeung/p/3683492.html
