所謂異步委托,主要用到了委托對象的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();
}
}
}