基於事件的非同步程式設計

2022-02-07 04:12:31 字數 3148 閱讀 1281

基於事件的非同步模式具有多執行緒應用程式的優點,同時隱藏了多執行緒設計中固有的許多複雜問題。 使用支援此模式的類,你將能夠:

同時執行多個操作,每個操作完成時都會接到通知。

等待資源變得可用,但不會停止(「阻止」)你的應用程式。

使用熟悉的事件和委託模型與掛起的非同步操作通訊。

支援基於事件的非同步模式的類將具有乙個或多個命名為methodnameasync的方法。 這些方法可能會建立同步版本的映象,這些同步版本會在當前執行緒上執行相同的操作。 該類還可能具有methodnamecompleted事件,並且可能會具有methodnameasynccancel(或只是cancelasync)方法。

public class asyncexample  

// class implementation not shown.

}

這裡虛構的asyncexample類有兩個方法,都支援同步和非同步呼叫。 同步過載的行為類似於方法呼叫,它們對呼叫執行緒執行操作;如果操作很耗時,則呼叫的返回可能會有明顯的延遲。 非同步過載將在另乙個執行緒上啟動操作,然後立即返回,允許在呼叫執行緒繼續執行的同時讓操作「在後台」執行。

非同步操作可以有兩個過載:單調用和多呼叫。 你可以通過方法簽名來區分這兩種形式:多呼叫形式有乙個額外的引數,即userstate。 使用這種形式,你的**可以多次呼叫method1async(string param, object userstate),而不必等待任何掛起的非同步操作的完成。 另一方面,如果你嘗試在前乙個呼叫尚未完成時呼叫method1async(string param),該方法將引發invalidoperationexception

多呼叫過載的userstate引數可幫助你區分各個非同步操作。 應分別為各個method1async(string param, object userstate)呼叫提供唯一值(例如,guid 或雜湊**);這樣,當各個操作完成時,事件處理程式便可以確定是哪個操作例項丟擲了完成事件。

如果你使用多呼叫過載,你的**將需要跟蹤掛起任務的userstate物件(任務 id)。 對於各個method1async(string param, object userstate)呼叫,通常會生成新的唯一userstate物件,並將它新增到集合中。 當對應於此userstate物件的任務引發完成事件時,你的完成方法實現將檢查asynccompletedeventargs.userstate並將此物件從集合中刪除。 在以這種方式使用時,userstate引數充當任務 id 的角色。

在為你對多呼叫過載的呼叫中的userstate提供唯一值時,一定要小心。 如果任務 id 不唯一,將導致非同步類引發argumentexception

我們必須能夠在非同步操作完成之前隨時取消它們,這一點很重要。 實現基於事件的非同步模式的類包含cancelasync方法(如果只有乙個非同步方法),或methodnameasynccancel方法(如果有多個非同步方法)。

允許多個呼叫採用userstate引數的方法,此類方法可用於跟蹤每個任務的生存期。cancelasync採用userstate引數,該引數可用於取消特定掛起任務。

一次只支援乙個掛起操作的方法(如method1async(string param))是不可取消的。

符合基於事件的非同步模式的類可以為跟蹤進度和增量結果提供事件。 此事件通常命名為progresschangedmethodnameprogresschanged,其對應的事件處理程式將使用progresschangedeventargs引數。

progresschanged事件的事件處理程式可以檢查progresschangedeventargs.progresspercentage屬性,以確定非同步任務完成百分比。 此屬性的範圍是 0 到 100,可用來更新progressbar.value屬性。 如果有多個非同步操作掛起,你可以使用progresschangedeventargs.userstate屬性來分辨出哪個操作在報告進度。

若要實現基於事件的非同步模式,你必須提供一些保證來確保類的行為正確且類的客戶端能夠依賴這種行為。

操作成功完成、出錯或取消時,始終應呼叫methodnamecompleted事件處理程式 。 任何情況下,應用程式都不應遇到這樣的情況:應用程式保持空閒狀態,而操作卻一直不能完成。 此規則的例外情況是:非同步操作本身設計為永不完成。

針對每個單獨的methodnameasync方法,請應用以下設計要求:

為了使類正確執行,應當使用給定應用程式模型(包括 asp.net 和 windows 窗體應用程式)的適當執行緒或上下文呼叫客戶端事件處理程式,這一點很重要。 我們提供了兩個重要的幫助器類,以確保你的非同步類在任何應用程式模型中都能正確執行,這兩個幫助器類是 asyncoperation 和 asyncoperationmanager。

asyncoperationmanager提供了createoperation方法,該方法會返回乙個asyncoperationmethodnameasync方法呼叫createoperation,且類使用返回的asyncoperation跟蹤非同步任務的生存期。

若要將程序、增量結果和完成情況報告給客戶端,請呼叫asyncoperation上的postoperationcompleted方法。asyncoperation負責將對客戶端事件處理程式的呼叫封送到合適的執行緒或上下文。

基於事件的非同步程式設計模式

public class backgroundworker component 通常的使用方法如下 在dowork中新增乙個事件處理程式,在該事件處理程式中呼叫耗時的操作 呼叫 runworkerasync啟動才操作。如果想要得到當前的更新進度,在progresschanged事件處理程式中處理,如...

基於事件的非同步程式設計模式

public class backgroundworker component 通常的使用方法如下 在dowork中新增乙個事件處理程式,在該事件處理程式中呼叫耗時的操作 呼叫 runworkerasync啟動才操作。如果想要得到當前的更新進度,在progresschanged事件處理程式中處理,如...

基於事件的非同步模式。

由於乙個類可以不用顯示的啟動或者管理執行緒而有多執行緒的能力,因此通過這就提供了乙個簡單的手段來實現,基於事件的非同步模式 event based asynchronous pattern eap 它同時也具有以下特徵 可協調的退出模式。當工作執行緒完成時,可以安全的更新wpf或者windowfor...