在 MSDN 的範例程式碼中,使用 WaitHandle.WaitAny 等待多個非同步任務完成。開發者發現:即使 WaitAny 只會在「任一」訊號被觸發時返回,但兩個任務似乎都執行了。這引發了疑問:主執行緒不應該在第一個任務完成後立即繼續,而不等待第二個任務嗎?
理論上 WaitAny 確實會在第一個訊號被設定(Set())時立即返回。但在實際執行環境中,存在以下因素導致「兩個任務都跑完」的現象:
WaitAny 返回後,可能不會立即獲得 CPU 時間片繼續執行;此期間,另一個工作執行緒可能已經完成工作並呼叫 Set()。Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles); // 阻塞直到任一訊號觸發
Console.WriteLine("Task {0} finished first (time waited={1}).", index + 1, (DateTime.Now - dt).TotalMilliseconds);
static void DoTask(Object state) {
AutoResetEvent are = (AutoResetEvent)state;
int time = 1000 * r.Next(2, 10); // 2~9 秒隨機延遲
Console.WriteLine("Performing a task for {0} milliseconds.", time);
Thread.Sleep(time);
are.Set(); // 通知完成
}
WaitAny 保證的是「等待邏輯」在第一個訊號到達時解除阻塞,但不保證主執行緒會在同一瞬間搶回 CPU 繼續執行。因此,其他任務在主執行緒真正繼續前完成工作,是正常的並發行為,不代表 WaitAny 失效。
CancellationToken 實作協作式取消。