非同步程式設計概觀
使用 IAsyncResult 設計模式的非同步作業 (Asynchronous Operation),會實作為兩個名稱為 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 方法簽章中的最後參數。
Begin OperationName 會立刻對呼叫的執行緒傳回控制項。如果 BeginOperationName 方法擲回例外狀況,例外狀況的擲回就會在非同步作業啟動之前發生。如果 BeginOperationName 方法擲回例外狀況,則不會叫用回呼 (Callback) 方法。
結束非同步作業
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 委派結束非同步作業。
請參閱
概念
以非同步的方式呼叫同步方法
使用 AsyncCallback 委派和狀態物件