非同步編程模式(六):基於事件的非同步呼叫模式

來源:互聯網
上載者:User

前一個日記介紹了以 WebResponse 為代表的支援IAsyncResult 非同步呼叫模式的組件,.NET基底類別庫中有部分組件實現 了另一種非同步模式,

這就是"事件架構非同步模式(EAP模式)"。

 

實現 了EAP模式的最典型組件是WebClient。

WebClient定義了以下兩個同步方法用於從WEB上下載檔案:

public void DownloadFile(string address, string fileName);

public void DownloadFile(Uri address, string fileName);

為了實現非同步呼叫,WebClient又定義了另兩個對應的非同步方法呼叫:

public void DownloadFileAsync(Uri address, string fileName);

public void DownloadFileAsync(Uri address, string fileName, object userToken);

EAP規定方法名以 Async 結尾的方法是非同步呼叫方法。

 

上面的方法,最後一個userToken參數前面已經說明了其作用。

其實很簡單,當應用程式多次調用DownloadFileAsync方法的這個重載形式啟動多個非同步下載任務時,這個參數用於區分這些任務。簡單地說,userToken

是非同步下載任務的標識。為每個正在執行的下載任務給出唯一的標識,是程式員的責任。

 

為了讓使用者中途取消任務,WebClient定義了以下方法:

public void CancelAsync();

由於任務可以被取消,因此問題產生了:非同步呼叫方法啟動以後,調用者如何知道任務是正常結束還是被中途取消的?

答案很簡單:非同步呼叫任務結束時,實現 了EAP的組件會激發一個相應的事件。以WebClient為例,當DownloadFileAsync方法啟動的非同步下載任務結束時,它會激發以下事件:

public event AsyncCompletedEventHandler DownloadFileCompleted;

這一事件有一個 AsyncCompletedEventArgs 類型的參數,其中包含了重要的資訊:

    public class AsyncCompletedEventArgs : EventArgs
{

public bool Cancelled { get; } //該值指示非同步作業是否已被取消。

public Exception Error { get; }//該值指示非同步作業期間發生的錯誤。

public object UserState { get; }//擷取非同步任務的唯一識別碼,如果使用者在啟動本任務時設定了任務標識,則此屬性值就是這個標識

}

由此可見,只需在 DownloadFileCompleted事件的回應程式法中檢查一下事件參數的Cancelled屬性,如果其值等於 true,就知道任務被中途取消了。

如果error屬性不為null,則任務執行過程中一定引發了異常。上述兩個條件都不滿足時,則任務是順利完成的。

當非同步任務可能要執行很長時間時,往往需要通知使用者當前工作完成的進度,為此,WebClient定義了以下事件:

public event DownloadProgressChangedEventHandler DownloadProgressChanged;

這個事件的參數中(DownloadProgressChangedEventArgs類型的對象)中包含了重要的資訊。

1. TotalBytesToReceive:要傳送的總位元組數。

2. BytesReceived:已接收的位元組數。

3.ProgressPercentage:工作完成的百分比。

 

掌握了以上知識,使用WebClient組件下載檔案就變得非常簡單,以下是一個代碼架構:

 

//從Web非同步下載網址為FileAddress的檔案

public void DownLoadFileFromWeb(string FileAddress)

{

WebClient client = new WebClient();

//掛接下載完成事件響應代碼

client.DownloadFileCompleted += client_DownloadFileCompleted;

//掛接下載進度事件響應代碼

client.DownloadProgressChanged += client_DownloadProgressChanged;

//啟動非同步下載檔案任務

Uri uri = new Uri(FileAddress);

client.DownloadStringAsync(uri);

}

下載完成事件響應代碼架構如下:

void client_DownloadFileCompleted(object sender,AsyncCompletedEventArgs e)

{

if(e.Cancelled) //使用者取消了操作

{

//處理代碼。。。。

}

if(e.Error != null) //有錯誤發生

{

//處理代碼

}

if(e.UserState != null) //取出任務標識

{

//處理代碼

}

//其它處理代碼。。。



}

下載進度事件響應代碼架構如下:

void client_DownloadProgressChanged(object sender,DownloadProgressChangedEventArgs e)

{

string info = "任務標識:{0},總資料:{1}位元組,已下載:{2}位元組,完成了{3}%。";

info = string.Format(info , e.UserState , e.TotalBytesToReceive , e.BytesReceived , e.ProgressPercentage);

//.....

}

 

 

依據前面的內容,我們可以對EAP形成以下的認識:

1.實現了EAP的組件定義 了以 Async 結尾的非同步呼叫方法。

2.當非同步呼叫任務結束時,會激發一個相應的事件,事件的參數包含重要的資訊。

3.實現 了EAP的組件可能會提供一個用於取消非同步任務的方法。

4.實現 了EAP的組件提供一個向使用者報告進度的事件。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.