1. 程式人生 > >【FastReport教程】介紹C#中的非同步程式設計(下)

【FastReport教程】介紹C#中的非同步程式設計(下)

【下載FastReport.Netdownload最新版本】

非同步程式設計模型出現在.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允許開發人員在單個方法中定義非同步函式。現在不需要建立非同步操作的開始和結束的函式,然後還有回撥函式。這當然有利於程式設計師的工作,降低了進入技術的門檻,並簡單地使程式設計變得愉快。 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將增加伺服器的頻寬。但是,如果您有少量流量(例如,客戶端 - 伺服器),則建立非同步流程的成本可能會抵消收益。在這種情況下,同步方法將更快地工作。