首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 非同步機制深度解析 (三):APM 核心 IAsyncResult 與 AsyncWaitHandle 同步控制完全攻略

     編輯:關於.NET

IAsyncResult 是 APM (Asynchronous Programming Model) 的核心協定物件,串聯 BeginXXX 傳回與 EndXXX 參數。本文詳細解析其介面成員、AsyncResult 實作細節、AsyncWaitHandle 三大同步等待策略,並附上 Jeffrey Richter PowerThreading 庫中的自訂 AsyncResult<T> 實作參考。

IAsyncResult 介面契約

屬性用途
AsyncWaitHandle取得 WaitHandle,供同步等待
IsCompleted非同步作業是否已完成
AsyncState使用者自訂狀態物件 (BeginXXX 最後一參數)
CompletedSynchronously是否同步完成 (極少用)

AsyncResult 類別關鍵擴充屬性

  • AsyncDelegate:取得原始委派物件,供 EndInvoke 使用。
  • EndInvokeCalled:偵測是否已呼叫 EndInvoke。

非同步執行流程示意

delegate decimal SalaryHandler(decimal salary, int months, decimal bonus);

SalaryHandler del = obj.YearlySalary;
IAsyncResult ar = del.BeginInvoke(100000, 15, 100000, OnCallback, 2000m);

DoOtherWork(); // 主執行緒繼續執行

void OnCallback(IAsyncResult ar)
{
    decimal extra = (decimal)ar.AsyncState;           // 2000
    SalaryHandler del = (SalaryHandler)((AsyncResult)ar).AsyncDelegate;
    decimal result = del.EndInvoke(ar);               // 取得回傳值
    Console.WriteLine(result + extra);
}

AsyncWaitHandle 三大等待策略

1. WaitOne — 等待單一作業完成

ar.AsyncWaitHandle.WaitOne(); // 封鎖直到完成
// 或 WaitOne(timeout) 限時等待

2. WaitAll — 等待所有作業完成

WaitHandle[] handles = { ar1.AsyncWaitHandle, ar2.AsyncWaitHandle };
WaitHandle.WaitAll(handles); // 等待最慢者完成

3. WaitAny — 等待任一作業完成

WaitHandle.WaitAny(handles); // 等待最快者完成

資源釋放責任

EndInvoke 後 WaitHandle 不會自動關閉,需手動釋放:

ar.AsyncWaitHandle.Close(); // 在 EndInvoke 後呼叫

自訂 AsyncResult<T> 實作參考 (PowerThreading 風格)

  1. AsyncResultNoResult:實作 IAsyncResult,使用 Interlocked.Exchange 原子更新狀態,ManualResetEvent 實作 AsyncWaitHandle。
  2. AsyncResult<TResult>:繼承上者,新增 TResult m_result 與強型別 EndInvoke()。
  3. LongTask:示範 BeginDoTask/EndDoTask 封裝耗時工作,內部使用 ThreadPool.QueueUserWorkItem 執行,完成時呼叫 SetAsCompleted。

非同步執行順序圖 WaitOne 封鎖效果 WaitAll 等待所有 WaitAny 等待任一

掌握 IAsyncResult 與 WaitHandle,即可精確控制非同步流程的同步點、逾時與取消,是進階非同步程式設計的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved