10章 異步程式設計模式
【摘要】:異步程式設計充分利用多線程技術帶來的好處,而不需要程式員了解多線程開發中的複雜細節。本章講述了基于IAsyncResult的異步模式、基于事件的異步模式。
第1節
程式的同步執行和異步執行
1、同步概念:
若在代碼中調用了一個方法,需要等待此方法所有的代碼執行完畢之後,才能回到原來的地方執行下一行代碼,這種程式運作方式稱為同步。
2、異步概念:
在調用方法之後,不用等待方法執行完成就馬上執行下一條語句,這種程式運作方式稱為異步。
3、異步調用的本質:不在主線程中執行,而在另一輔助線程中與主線程并行執行。
第2節
基于委托的異步程式設計模式
1、 當定義一個委托時,編譯器會生成如下的類,借助委托的BeginInvoke和EndInvoke方法實作異步調用。
Public sealed class CalculateFolderSizeDelegate:MulticastDelegate
{
Public CalculateFolderSizeDelegate(object target,int methodPtr)
{ ……}
Public virtual <方法傳回值類型> Invoke (<輸入和輸出參數>)
Public virtual IAsyncResult BeginInvoke(<輸入和輸出變量>,AsyncCallback
callback,object asyncState)
{ ……}
Public virtual <方法傳回值類型>
EndInvoke(<聲明為ref或out的參數>,IAsyncResult result)
A、
BeginInvoke的第一個參數為方法簽名中的參數清單,第二個參數callback是當異步調用結束時自動回調的方法,第三個參數asyncState用于向第二個參數所确定的callback回調方法提供額外的資訊。
B、 BeginInvoke方法傳回一個IAsyncResult接口的對象。
Public interface IAsyncResult
Object AsyncState {get;}
WaitHandle AsyncWaitHandle { get;}
Bool CompletedSynchronously {get;}
Bool IsCompleted {get;}
}
C、
EndInvoke:發現異步調用完成時,它取出此異步調用方法執行的結果作為其傳回值,如果異步調用方法有聲明為ref和out的參數,它也負責填充它。
第3節 基于委托的異步程式設計模式的實踐
1、 當異步調用完成之時,調用者線程如何知道調用的執行情況。
A、 使用輪詢 如通過IAsyncResult對象的IsCompleted或AsyncWaitHandle實作。
B、 異步回調。
2、 處理異常調用中的異常。
需在EndInvoke方法所在的代碼處捕獲異步調用抛出的異常。
3、實作異步調用任務的同步問題。
第4節 實作IAsyncResult異步調用模式的元件
1、 在.NET基類型庫中,有一些現有的元件直接實作了IAsyncResult異步調步模式,這些元件通常同時提供某個方法的同步與異步調用形式。
以WebRequest 為例。
IAsyncResult BeginGetResponse(AsyncCallback callback, object
state) //異步
IAsyncResult BeginGetRequestStream(AsyncCallback callback, object
state) //異步
Stream EndGetRequestStream(IAsyncResult asyncResult)
WebResponse EndGetResponse(IAsyncResult asyncResult)
Stream GetRequestStream() //同步
WebResponse GetResponse() //同步
2、 方法有如下特點:
A、凡有一個BeginXXX的,一定有一個“EndXXX”方法相對應。
B、每組“BeginXXX/EndXXX”,一定有一個對應的“XXX”同步方法。
C、“EndXXX”方法與對應的同步方法“XXX”的傳回值類型相同。
D、“BeginXXX”傳回一個IAsyncResult對象,而“EndXXX”方法的參數接收此對象。
3、此模式前基于委托的異步調用模式幾乎一模一樣,是以前面介紹的程式設計技巧可以繼續使用。
第5節 基于事件的異步調用模式
1、 在.NET基類庫中有部分元件實作了另一種異步模式,這就是基于事件的異步模式(Event-based Asynchronous
Pattern),簡稱為EAP。
以WebClient 為例。
public void DownloadFileAsync(Uri address, string fileName);
public void DownloadFileAsync(Uri address, string fileName,object
userToken);
public void CancelAsync(); //取消任務
2、 EAP有如下特點:
A、 實作了EAP的元件定義了以“Async”結尾的異步調用方法。
B、
當異步調用任務結束時,會激發一個相應的事件,事件的參數包含重要的資訊。
如
WebClient會激發DownloadFileCompleted事件,參數資訊存在 AsyncCompletedEventArgs對象中。
C、 實作了EAP的元件可能會提供一個用于取消異步任務的方法。
D、實作了EAP的元件提供一個向使用者報告進度的事件。
如WebClient的 DownloadProgressChanged 事件。
3、【感】:用EAP元件原來是這麼簡單。
第6節 異步程式設計小結
1、 分類:異步程式設計分為 基于IAsyncResult的異步模式和基于事件的異步模式。而前者又分為基于委托的異步調用與使用類基類庫中的元件兩種。
2、 異步調用的每個方法都是獨立的線程中執行的,其本質上就是一種多線程程式。
3、 适合場景:
A、 直接使用基類庫中擁有異步調用特性的元件,如WebClient。
需要在背景運作一些較耗費時間的任務,這些任務彼此互相獨立,而且沒有代碼直接通路可視化的控件。