【FastReport教程】介紹C#中的異步編程(下)
【下載FastReport.Net最新版本】
異步編程模型出現在.Net Framework的第一個版本中。APM允許使用兩種方法創建同步方法的異步版本 - Begin 和End 。 所以,只有兩種方法:
public IAsyncResult Begin{MethodName}(TIn[] args, AsyncCallback callback, object userState =null) { … }
和:
public TResult End{MethodName}(IAsyncResult result) { ... }
Begin {MethodName}方法啟動異步操作。它接受參數args,callback--執行異步方法后調用的方法的委托,userState對象,用于將有關特定應用程序狀態的信息傳遞給異步操作結束時調用的方法。 該方法返回IAsyncResult類型的對象,該對象存儲有關異步操作的信息。 End {MethodName}方法終止異步操作。它接受一個輸入對象,類型為IAsyncResult,并返回TResult,它實際上返回此方法的同步副本中定義的類型。 讓我們看一下簡化示例中如何使用此模板:
public void Button_Click (...) { WebRequest request = WebRequest.Create(url); request.BeginGetResponse(Callback , request); } public void Callback(IAsyncResult ar) { WebRequest request = (WebRequest) ar.AsyncState; try { var response = request.EndGetResponse(ar); // Code does something with successful response } catch (WebException e) { // Error handling code } }
我們在按鈕單擊事件處理程序中調用了Begin方法。作為參數,我們將回調傳遞給此方法。并且,已經在回調本身中我們稱為對方法 - 結束。 異步編程模型的缺點包括:
- 創建回調函數的必要性;
- 缺乏中止操作的方法。
- 沒有拒絕調用回調方法的方法,如果它是在操作開始時傳遞的。
- 沒有通知操作進度或中期結果。
基于事件的異步模式
這種異步編程模式出現在.Net框架的第二個版本中。它基于事件和異步方法。實現此模板的類將包含方法MethodNameAsync和MethodNameAsyncCancel(如果需要操作取消處理)和MethodNameCompleted事件。在同一個類中,您可以放置??使用相同線程的方法的同步版本。大多數情況下,在使用Web服務時會使用此模板。例如,ajax實現基于事件的異步模式。您只能在MethodNameCompleted事件處理程序中獲取異步操作的結果并處理錯誤。
基于事件的異步編程模式解決了前一個問題:
- 聲明獲取異步操作結果的方法;
- 沒有通知操作進度的機制。
但是,此模板仍有許多缺點:
- 無法將操作調用的上下文(用戶數據)傳送到結果處理方法;
- 并非所有操作都可以中斷。只支持隊列中一個操作的方法不能被中斷;
- 無法在上下文中指定將調用哪個線程回調方法。
基于任務的異步模式(TAP)
異步編程的第三個模板出現在.Net Framework 4.0中。從標題中可以清楚地看出它基于任務的使用。TAP的基礎是System.Threading.Tasks.Task和System.Threading.Tasks.Task 兩種類型。
TAP允許開發人員在單個方法中定義異步函數?,F在不需要創建異步操作的開始和結束的函數,然后還有回調函數。這當然有利于程序員的工作,降低了進入技術的門檻,并簡單地使編程變得愉快。 TAP使用任務來執行操作。對于每個任務,使用一個單獨的線程,該線程取自線程池。任務完成后,線程返回池。
修飾符“async” - 此修飾符應用于方法或lambda表達式或匿名方法 - 它表示該方法是異步的,并表示此方法中出現一次或多次wait語句的可能性。 我們來看一個方法定義的例子:
public async Task<int>MyProcessAsync() { … Var Overtime = await new ERP().ProcessOvertime(emp); … }
注意關鍵字async和await。這些是表示正在使用基于任務的異步模式的運算符。async修飾符表示該方法是異步的。并且可以在方法內調用await語句一次或多次。它暫停執行任務,直到獲得結果,同時線程繼續工作。
這是一個從生活中使用TAP的例子。調用Web服務:
static async Task<string> SendMessageAsync() { var client = new MyServiceClient(); var task = Task.Factory.StartNew(() => client.SendMessageAsync("Message")); var result = await task; return result; }
這是另一種調用方式,更簡單,更容易理解:
static async Task<string> SendMessageAsyncNew() { var client = new MyServiceClient(); var result = await client.SendMessageAsync("Message"); return result; }
使用await的這個“輕量級”版本可以在.Net Framework 4.5中找到。 基于異步任務的方法解決了以前模板的大多數問題。然后你和中斷異步操作的能力,以及一個簡單的實現方法,跟蹤操作進度的能力。 目前,Microsoft建議在開發組件時使用此模板實現異步調用。 至于使用這個模板的權宜之計。使用TAP將增加服務器的帶寬。但是,如果您有少量流量(例如,客戶端 - 服務器),則創建異步流程的成本可能會抵消收益。在這種情況下,同步方法將更快地工作。