掌握 Task 等待模式與標準化例外處理,是撰寫健壯並行程式的關鍵。
task.Wait(); // 無限期等待
task.Wait(2000); // 等待 2 秒,回傳 bool 是否完成
task.Wait(2000, token); // 可攜帶 CancellationToken
注意:Task 內部拋出例外會在 Wait() 重新拋出。
Task.WaitAll(task1, task2); // 全部完成才返回
Task.WaitAll(tasks, 5000); // 含逾時
Task.WaitAll(tasks, token); // 可取消等待
任一 Task 失敗/取消/拋出例外,WaitAll 即拋出 AggregateException。
int index = Task.WaitAny(task1, task2); // 回傳完成任務索引
int index = Task.WaitAny(tasks, 3000); // 含逾時
TPL 將多任務例外封裝於 AggregateException,InnerExceptions 屬性保存所有內部例外。
try {
Task.WaitAll(task1, task2, task3);
} catch (AggregateException ex) {
foreach (var inner in ex.InnerExceptions) {
Console.WriteLine($"Type: {inner.GetType()}, Source: {inner.Source}");
}
}
ex.Handle(inner => ...) 回傳 true 表示已處理(不再向上拋出),false 保留重拋:
ex.Handle(inner => {
if (inner is OperationCanceledException) {
// 處理取消請求
return true;
}
return false; // 未知例外向上傳播
});
此模式可精準控制例外流向,避免吞沒關鍵錯誤。