關於委託的這3個方法的詳細說明可以參考這文章
http://www.cnblogs.com/aierong/archive/2005/05/25/162181.html
我們先來瞭解這2個方法和一個委託和一個介面:
(1)
BeginInvoke 方法可啟動非同步呼叫。
它與您需要非同步執行的方法具有相同的參數,另外它還有兩個選擇性參數。第一個參數是一個 AsyncCallback 委託,該委託引用在非同步呼叫完成時要調用的方法。第二個參數是一個使用者定義物件,該對象可向回調方法傳遞資訊。BeginInvoke 立即返回,不等待非同步呼叫完成。BeginInvoke 會返回 IAsyncResult,這個結果可用於監視非同步呼叫進度。
結果對象IAsyncResult是從開始操作返回的,並且可用於擷取有關非同步開始操作是否已完成的狀態。
結果對象被傳遞到結束操作,該操作返回調用的最終傳回值。
在開始操作中可以提供可選的回調。如果提供回調,在調用結束後,將調用該回調;並且回調中的代碼可以調用結束操作。
(2)
EndInvoke 方法檢索非同步呼叫的結果。
調用 BeginInvoke 後可隨時調用 EndInvoke 方法;如果非同步呼叫尚未完成,EndInvoke 將一直阻止調用線程,直到非同步呼叫完成後才允許調用線程執行。EndInvoke 的參數包括您需要非同步執行的方法的 out 和 ref 參數以及由 BeginInvoke 返回的 IAsyncResult。
(3)
AsyncCallback委託用於指定在開始操作完成後應被調用的方法
AsyncCallback委託被作為開始操作上的第二個到最後一個參數傳遞
代碼原型如下:
[Serializable]
public delegate void AsyncCallback(IAsyncResult ar);
AsyncCallback為用戶端應用程式提供完成非同步作業的方法。開始非同步作業時,該回調委託被提供給用戶端。AsyncCallback 引用的事件處理常式包含完成用戶端非同步任務的程式邏輯。
AsyncCallback 使用 IAsyncResult 介面擷取非同步作業的狀態。
(4)
IAsyncResult介面
它表示非同步作業的狀態.
該介面定義了4個公用屬性
代碼原型如下:
public interface IAsyncResult
實際上,發起和完成.NET非同步呼叫有4種方案可供你選擇
1.方案1-使用EndInvoke等待非同步呼叫
非同步執行方法最簡單的方式是通過調用委託的 BeginInvoke 方法來開始執行方法,在主線程上執行一些工作,然後調用委託的 EndInvoke 方法。EndInvoke 可能會阻止調用線程,因為它直到非同步呼叫完成之後才返回。這種技術非常適合檔案或網路操作,但是由於 EndInvoke 會阻止它,所以不要從服務於使用者介面的線程中調用它。
還是先來段自己喜歡的控制台代碼:
1using System;
2
3namespace ConsoleApplication1
4{
5 class Class1
6 {
7 public delegate void AsyncEventHandler();
8
9 void Event1()
10 {
11 Console.WriteLine("Event1 Start");
12 System.Threading.Thread.Sleep(2000);
13 Console.WriteLine("Event1 End");
14 }
15
16 void Event2()
17 {
18 Console.WriteLine("Event2 Start");
19 int i=1;
20 while(i<1000)
21 {
22 i=i+1;
23 Console.WriteLine("Event2 "+i.ToString());
24 }
25 Console.WriteLine("Event2 End");
26 }
27
28 void CallbackMethod(IAsyncResult ar)
29 {
30 ((AsyncEventHandler) ar.AsyncState).EndInvoke(ar);
31 }
32
33
34 [STAThread]
35 static void Main(string[] args)
36 {
37 long start=0;
38 long end=0;
39 Class1 c = new Class1();
40 Console.WriteLine("ready");
41 start=DateTime.Now.Ticks;
42
43 AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
44 IAsyncResult ia=asy.BeginInvoke(null,null);
45 c.Event2();
46 asy.EndInvoke(ia);
47
48 end =DateTime.Now.Ticks;
49 Console.WriteLine("時幅差="+ Convert.ToString(end-start) );
50 Console.ReadLine();
51 }
52 }
53}
54
此程式簡單,非同步處理過程在代碼43-46這幾行
結果如下:
現在讓我們來看看同步處理
修改代碼43-46這幾行代碼:
c.Event1();
c.Event2();
結果如下:
前者的時幅大大小於後者
我們可以明顯地看到非同步啟動並執行速度優越性
2.方案2-輪詢非同步呼叫完成
由 BeginInvoke 返回的IAsyncResult.IsCompleted屬性擷取非同步作業是否已完成的指示,發現非同步呼叫何時完成.
從使用者介面的服務線程中進行非同步呼叫時可以執行此操作。輪詢完成允許調用線程在非同步呼叫在 ThreadPool 線程上執行時繼續執行。
再次修改代碼43-46這幾行代碼:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
while(!ia.IsCompleted)
{
}
asy.EndInvoke(ia);
3.方案3-使用WaitHandle等待非同步呼叫
IAsyncResult.AsyncWaitHandle屬性擷取用於等待非同步作業完成的WaitHandle
WaitHandle.WaitOne方法阻塞當前線程,直到當前的WaitHandle收到訊號
使用WaitHandle,則在非同步呼叫完成之後,但在通過調用EndInvoke結果之前,可以執行其他處理
再次修改代碼43-46這幾行代碼:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
ia.AsyncWaitHandle.WaitOne();
4.方案4-非同步呼叫完成時執行回調方法
如果啟動非同步呼叫的線程不需要是處理結果的線程,則可以在調用完成時執行回調方法。回調方法在 ThreadPool 線程上執行。
若要使用回調方法,必須將引用回調方法的 AsyncCallback 委託傳遞給 BeginInvoke。也可以傳遞包含回調方法將要使用的資訊的對象。例如,可以傳遞啟動調用時曾使用的委託,以便回調方法能夠調用 EndInvoke。
再次修改代碼43-46這幾行代碼:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
asy.BeginInvoke(new AsyncCallback(c.CallbackMethod),asy);
c.Event2();