非同步程式設計概觀
更新:2007 年 11 月
使用 IAsyncResult 設計模式的非同步作業會被實作成兩個方法,名稱為 BeginOperationName 及 EndOperationName,分別負責開始和結束非同步作業 OperationName。例如,FileStream 類別會提供 BeginRead 和 EndRead 方法,以非同步方式從檔案讀取位元組。這些方法會實作 Read 方法的非同步版本。
在呼叫 BeginOperationName 之後,應用程式可以繼續對呼叫執行緒執行指令,而非同步作業會在不同的執行緒上執行。對於每個 BeginOperationName 呼叫,應用程式也應該呼叫 EndOperationName 以取得作業的結果。
開始非同步作業
BeginOperationName 方法會開始非同步作業 OperationName,並傳回實作 IAsyncResult 介面的物件。IAsyncResult 物件會儲存有關非同步作業的資訊。下表顯示非同步作業的相關資訊。
成員 |
說明 |
---|---|
選擇性的應用程式特定物件,含有非同步作業的相關資訊。 |
|
WaitHandle 可以用來封鎖應用程式執行,直到非同步作業完成為止。 |
|
這個值指出,非同步作業是否是在用來呼叫 BeginOperationName 的執行緒上完成的,而不是在個別 ThreadPool 執行緒上完成。 |
|
一個值,指示非同步作業是否已經完成。 |
BeginOperationName 方法會使用任何參數,而這些參數是以傳值 (By Value) 或傳址 (By Reference) 方式,在方法同步版本的簽章 (Signature) 中宣告的。任何 Out 參數都不是 BeginOperationName 方法簽章的一部分。BeginOperationName 方法簽章也包括其他兩個參數。其中的第一個參數會定義 AsyncCallback 委派 (Delegate),而這個委派會參考非同步作業完成時所呼叫的方法。如果不要在作業完成時叫用 (Invoke) 方法,呼叫端可以指定 null (Visual Basic 中的 Nothing)。第二個參數則是使用者定義的物件。這個物件可以用來傳遞應用程式特定狀態資訊給非同步作業完成時所叫用的方法。如果 BeginOperationName 方法使用其他作業特定參數 (例如用來儲存從檔案讀取之位元組的位元組陣列),AsyncCallback 和應用程式狀態物件就會是 BeginOperationName 方法簽章中的最後參數。
BeginOperationName 會立即對呼叫的執行緒傳回控制項。如果 BeginOperationName 方法擲回例外狀況,就是在啟動非同步作業前擲回的。如果 BeginOperationName 方法擲回例外狀況,就會引發回呼方法。
結束非同步作業
EndOperationName 方法會結束非同步作業 OperationName。EndOperationName 方法的傳回值與其同步對應方法所傳回的型別相同,而且是非同步作業特定的。例如,EndRead 方法會從 FileStream 讀取位元組數,並且 EndGetHostByName 方法會傳回包含主機電腦資訊的 IPHostEntry 物件。EndOperationName 方法會使用在此方法之同步版本的簽章中,所宣告的任何 Out 或 Ref 參數。除了同步方法中的參數外,EndOperationName 方法還包括 IAsyncResult 參數。呼叫端必須傳遞 BeginOperationName 的對應呼叫所傳回的執行個體。
如果呼叫 EndOperationName 時,IAsyncResult 物件所代表的非同步作業還沒有完成,EndOperationName 就會封鎖呼叫執行緒直到非同步作業完成為止。非同步作業所擲回的例外狀況,都是從 EndOperationName 方法擲回。使用相同 IAsyncResult 多次呼叫 EndOperationName 方法的效果尚未定義。同樣地,使用並非由相關 Begin 方法傳回的 IAsyncResult,呼叫 EndOperationName 方法也尚未定義。
注意事項: |
---|
對於這兩種未定義的案例,實作器可能都會考慮擲回 InvalidOperationException。 |
注意事項: |
---|
這個設計模式的實作器必須將 IsCompleted 設定為 true、呼叫非同步回呼方法 (如果指定了一個),並對 AsyncWaitHandle 發出信號,以通知呼叫端非同步作業已經完成。 |
應用程式開發人員擁有數種設計選擇,以存取非同步作業的結果。正確的選擇,取決於應用程式是否具有可以在作業完成時執行的指令。如果直到接收非同步作業的結果,應用程式都不能執行任何其他工作,表示應用程式必須封鎖起來,直到能夠取得結果為止。若要封鎖直到非同步作業完成,您可以使用下列其中一個方法:
從應用程式的主執行緒呼叫 EndOperationName,並封鎖應用程式的執行,直到作業完成為止。如需說明這個技巧的範例,請參閱以結束非同步作業的方式封鎖應用程式執行。
使用 AsyncWaitHandle 封鎖應用程式執行,直到一或多個作業完成為止。如需說明這個技巧的範例,請參閱使用 AsyncWaitHandle 封鎖應用程式執行。
不需要在非同步作業完成時封鎖的應用程式,可以使用下列其中一個方法:
定期檢查 IsCompleted 屬性,以輪詢作業完成狀態,並在作業完成時呼叫 EndOperationName。如需說明這個技巧的範例,請參閱輪詢非同步作業的狀態。
使用 AsyncCallback 委派,以指定要在作業完成時叫用的方法。如需說明這個技巧的範例,請參閱使用 AsyncCallback 委派結束非同步作業。