對比以上的兩段代碼,我們不難發現其中的差別,與上一段代碼相比,我們在這裡使用了BeginInvoke()的另一個重載方法。其中的一個參數即為BeginInvoke()方法指定的回調方法,在相應的目標方法執行完畢之後將調用該回調方法,並且可以在相應的回調用法中調用結束動作。
這裡值得順帶一提的是,有關我寫上一篇隨筆時留下的關於Control.Invoke()方法的疑問。
大家可能會發現,本節中提到的[delegate].Invoke()方法與上節中提到的Control.Invoke()方法在名稱書寫上是一樣的,那麼他們在功能上是否存在著些許的相似之處呢?以下是我做出的總結:
Return Work Thread
Control.Invoke 完成工作 強制於 UI Thread
Control.BeginInvoke 立即 強制於 UI Thread
[delegate].Invoke 完成工作 Call Invoke 的 Thread
[delegate].BeginInvoke 立即 新的背景 Thread
從中大家可以發現一個關鍵的問題,不論委托對象也好,Control對象也好,他們的Invoke ()方法都是以絕對同步的方式執行,而BeginInvoke()方法則是以絕對異步的方式執行。
在這裡,我之所以強調“絕對” 兩個字,是為了提醒讀者雖然“異步”與“多線程”間存在著密切的聯系,但異步並不等於在原程序的基礎上開設子線程,同步亦並非一定要針對單線程的程序而言。
我們不妨再以上一篇隨筆中“跨線程操控控件”這段代碼來說明問題,當然為說明問題方便,我做了部分調整:
using System.Threading;
namespace MulTrdDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//定義委托類型
public delegate void TreadDelgate();
//初始化子線程對象
private Thread demoThread = null;
private void button1_Click(object sender, EventArgs e)
{
demoThread = new Thread(new ThreadStart(ThreadProcUnsafe));
demoThread.Start();
}
public void ThreadProcUnsafe()
{
if (this.textBox1.InvokeRequired)
{
TreadDelgate Objdelegate = new TreadDelgate(SetText);
this.Invoke(Objdelegate, new object[] {});
MessageBox.show("委托方法已返回!");
}
else
{
SetText();
}
}
private void SetText()
{
Thread.sleep(5000);//人為延長方法的執行時間
string text = "這個控件的內容是由子線程實現的";
this.textBox1.Text = text;
}
}
}
大家留心我在代碼中用紅筆勾注的這句代碼,如果說委托方法在調用時立即返回,那麼這句代碼會馬上執行。不過,當大家運行時就會發現,這句代碼是在SetText()方法返回之後才執行的——這便是Control.Invoke()方法所起到的作用了。大家注意,本身這是一個多線程程序,按理說this.Invoke(Objdelegate, new object[] {});將相應的委托方法強制到主線程去執行,子線程是不受影響的,不過這裡卻是完全按照單線程的方式在執行的。這就是所謂的“絕對同步”,也就是說即使是多線程也同樣會強制按照單線程的方式來執行。這裡和本節提到的[delegate].Invoke ()方法執行方式完全一致。
感興趣的讀者也可以嘗試將this.Invoke()改為this.BeginInvoke(),查看一下運行效果。沒錯,和本節提到的[delegate].BeginInvoke ()方法執行方式完全一致。
也就是說,不管當前運行的環境是多線程還是單線程。同步方法會強制程序按照單線程的方式執行,異步方法則強制程序按照多線程方式執行。
其實,從寫第一篇關於委托的隨筆開始,就不斷有園友問我:什麼時候采用委托?在這裡,我並不打算對這個問題做出正面回答。原因很簡單——程序效果是單一的,實現方式則是多種多樣的。這裡提供本人在學習委托過程中的幾個相當有代表性的實例,僅僅是為了幫助讀者們以自己的方式來理解委托的用途。每個人有每個人看待事物的獨特方式,別人的思想到你身上不一定就行得通。
真心希望以上的幾篇隨筆可以幫助讀者對委托有一個更深入的認識,屆時大家自然可以真真正正的總結出適合於自己思路的委托使用環境,以及,你自己眼中所看到的委托的真正面貌。