結束 Task 基礎系列,補充三項實用主題:任務狀態查詢、延遲初始化啟動、死鎖與例外處理常見陷阱。
回傳 TaskStatus 列舉值:
Created:已初始化,未進入排程器WaitingForActivation:等待排程器啟動WaitingToRun:已排程,等待執行Running:正在執行WaitingForChildrenToComplete:父任務等待子任務完成RanToCompletion:正常完成Canceled:已取消Faulted:執行期間拋出例外結合 Lazy<T> 與 TaskFactory.StartNew,僅在首次存取 Value 時建立並啟動 Task,減少非必要開銷:
Func<string> body = () => { Console.WriteLine("Working..."); return "Result"; };
Lazy<Task<string>> lazyTask = new Lazy<Task<string>>(() => Task<string>.Factory.StartNew(body));
Console.WriteLine("Before access");
Console.WriteLine($"Result: {lazyTask.Value.Result}"); // 此處才真正建立並啟動 Task
優勢:Lazy<T> 初始化成本遠低於 Task,適合條件性使用的長時間任務。
多個 Task 互相等待對方結果形成循環依賴:
Task<int>[] tasks = new Task<int>[2];
tasks[0] = Task.Factory.StartNew(() => tasks[1].Result + 100);
tasks[1] = Task.Factory.StartNew(() => tasks[0].Result + 100); // 互相等待 → 死鎖
Task.WaitAll(tasks); // 永久阻塞
解決:避免 Task 執行體內直接依賴其他 Task 結果,改用續發任務或資料流程設計。
參考系列第五篇:使用 Task.WaitAll 捕獲 AggregateException,透過 Handle 方法分類處理已知/未知例外。