天天看點

[轉]《.NET4.0 面向對象程式設計漫談》讀書筆記 ——第10章 異步程式設計模式

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。

需要在背景運作一些較耗費時間的任務,這些任務彼此互相獨立,而且沒有代碼直接通路可視化的控件。