延續儲存在 m_continuationObject 中,可能型別包括:
以下是流程簡單的描述
狀態:Task 完成(Completed)
→ 觸發延續處理
→ 呼叫 Task.FinishContinuations()
→ 取出 m_continuationObject
→ 延續型別判斷:
→ 單一委派:直接排程或內聯呼叫
→ 清單型別:逐一排程/呼叫
→ 特殊型別:依邏輯處理
→ 排程至執行環境:
→ 若有 SynchronizationContext 且未設定 ConfigureAwait(false):使用 Post
→ 否則:使用預設 TaskScheduler(ThreadPool)
關鍵原始碼點:
延續排程策略:
TaskScheduler 負責決定延續執行位置,預設實作為 ThreadPoolTaskScheduler,將工作排入 ThreadPool。
以下是流程簡單的描述
狀態:建立 Task (Created)
→ 呼叫 Task.ScheduleAndStart
→ 交由 TaskScheduler.QueueTask
→ ThreadPool.UnsafeQueueCustomWorkItem
→ 放入執行緒本地佇列(Work-Stealing)
→ Worker 執行 TryExecuteTaskInline
→ 進入執行狀態
ThreadPool 核心結構:
關鍵原始碼觀察點:
名稱 | 職責 | 典型來源 | 影響 |
---|---|---|---|
SynchronizationContext | 特定框架邏輯上下文返還 | WPF、WinForms、舊版 ASP.NET | 控制 await 執行位置 |
ExecutionContext | 安全性、AsyncLocal、文化設定傳遞 | CLR 執行層 | 影響延續成本與呼叫鏈 |
降低成本策略:
動機:消除已同步完成 Task 的物件配置開銷,降低 GC 壓力。
ValueTask 包裝型別:
使用要點:
AsyncTaskMethodBuilder 與 AsyncValueTaskMethodBuilder 共同功能:
ValueTask Builder 優化:同步完成時直接生成 ValueTask,避免 Task 配置。
模式 | 行為 | 適用場景 |
---|---|---|
預設 | 捕捉 SynchronizationContext 與 ExecutionContext | UI 層、需回原邏輯上下文 |
ConfigureAwait(false) | 僅捕捉 ExecutionContext | 函式庫、後端服務 |
ConfigureAwait(ForceYield) (.NET 9+) | 完成後仍強制排程 | 測試、避免深遞迴堆疊 |
使用 Unsafe Awaiter | 不捕捉 ExecutionContext | 高性能內部路徑 |
原始碼實作:ConfiguredTaskAwaitable.ConfiguredTaskAwaiter 決定排程策略。
Task 需主動觀察取消權杖:
await 已取消 Task 時,拋出含權杖的 OperationCanceledException。