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