所謂異步委派,主要用到了委派物件的 BeginInvoke() 方法以及 EndInvoke() 方法。和同步執行的 Invoke() 方法相比,這兩個方法具有如下的特性:
BeginInvoke() 方法以異步方式開啟目標方法,也就是說,其在呼叫之後會立即返回,即使是執行時間相當長的目標方法對於 BeginInvoke() 而言也不會帶來任何的阻塞。如果是依靠委派來執行耗時相當長的方法,並且我們不急於得到方法的返回值(亦或是操控其他物件的效果)或者我們根本就不用得到方法的返回值,則以這種異步方式來執行無疑是最合適的。
EndInvoke() 方法是與 BeginInvoke() 方法配對執行的,用於檢索呼叫結果。相對前者而言,如果異步呼叫的方法尚未執行完畢,則 EndInvoke() 將一直遭到阻塞,直至異步方法執行完畢。其傳入參數為呼叫 BeginInvoke() 時返回的 IAsyncResult 型別物件。
有關 BeginInvoke()、EndInvoke() 方法,以及 IAsyncResult 介面物件的詳細用法 everx 朋友在他的隨筆中進行了較為全面的闡述,在這裡為大家推薦一下:
異步委派的用法
我們再來看上述程式碼。Main() 方法的第二句以異步方式執行委派方法,方法則在剛開始執行時被迫暫停 5 秒,然而,執行時我們會發現「委派方法執行中....」這句話幾乎是在程式開始的瞬間就被顯示出來了。這說明,BeginInvoke() 在執行後是馬上返回的,並未遭到任何的阻塞。在這之後,我們將 Main() 方法同樣暫停 5 秒,而後以 EndInvoke() 獲得委派方法的返回效果:「委派方法呼叫成功!」。這樣,我們實現了委派的異步呼叫。
大家發現了嗎?這種異步委派機制和 C# 中的多執行緒機制有異曲同工之妙!而事實上,在相應的目標方法中看執行緒號和主執行緒確實是不一樣的。不過,在查閱了相關的一些資料之後,我還是得知了其中的一些細微的差別。這裡推薦給大家一篇來自 Kuffy Wang 朋友的文章:
異步委派與多執行緒的區別
下面我們使用回呼方式來執行異步委派:
9(2)回呼式異步委派
using System.Threading;
namespace AsyncDelegate
{
class Program
{
// 定義委派
delegate void MyDelegate();
static void Main(string[] args)
{
// 宣告委派物件
MyDelegate ObjDelegate = new MyDelegate(ObjDelegateFun);
// 使用異步方式
IAsyncResult ObjIr = ObjDelegate.BeginInvoke(new AsyncCallback(CallbackFun), ObjDelegate);
Console.WriteLine("委派方法執行中
.");
Console.ReadLine();
}
static private void ObjDelegateFun()
{
Thread.Sleep(5000);
Console.WriteLine("委派方法呼叫成功!");
}
static private void CallbackFun(IAsyncResult ar)
{
MyDelegate ObjDelegate = (MyDelegate)ar.AsyncState;
ObjDelegate.EndInvoke(ar);
Console.WriteLine("回呼方法執行完畢!");
Console.ReadLine();
}
}
}