iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0

Task/ValueTask 與非同步排程器原始碼導讀

現代 .NET 的非同步模型(async/await + Task Parallel Library, TPL)是 I/O 服務、雲端 API、IoT 邊緣裝置與高效能服務的核心。理解 Task / ValueTask 與排程器(TaskScheduler / ThreadPool)內部實作,有助:

  • 寫出低延遲、低配置(allocation)的非同步程式碼
  • 避免常見阻塞 / 死鎖 / ThreadPool starvation
  • 評估何時值得從 Task 優化為 ValueTask
  • 正確診斷「為何卡住 / 為何延續不在預期執行緒」

本文提供心智模型 → 原始碼對照 → 實驗 → 效能與陷阱。建議先通讀,再帶著具體問題進入 runtime 原始碼。

核心構件:Task(結果容器 + 延續列表)、TaskScheduler(排程策略)、ThreadPool(執行工作者)、ExecutionContext(流程上下文)、SynchronizationContext(邏輯同步環境)、ValueTask(高命中同步結果的分配優化封裝)、IValueTaskSource(進階可重用狀態源)。


async/await 編譯後做了什麼

語法糖展開(以 async Task<int> Foo() 為例):

  1. 產生隱藏狀態機型別:實作 IAsyncStateMachine,包含欄位:int <>1__stateAsyncTaskMethodBuilder<int> <>t__builder、暫存區(locals / awaiter)
  2. 原始方法本體成為一個「建立並啟動狀態機」的外殼;真正流程在 MoveNext()
  3. 每個 await expr
    • expr.GetAwaiter() → 檢查 IsCompleted
    • 未完成:儲存 state、註冊 continuation:awaiter.OnCompleted(stateMachineBoxed.MoveNext);方法先 return(尚未完成的 Task)
    • 完成:直接 awaiter.GetResult() 繼續下一段
  4. 結尾呼叫 builder.SetResult(value) 或例外路徑 builder.SetException(ex)

對照原始碼(System.Runtime.CompilerServices):

  • AsyncTaskMethodBuilder / AsyncTaskMethodBuilder<T>
  • AsyncValueTaskMethodBuilder / <T>
  • TaskAwaiter / ConfiguredTaskAwaitable

關鍵方法 AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted → 包裝 continuation + 註冊。


上一篇
Span / Memory 互轉技巧
下一篇
Task 內部結構
系列文
新 .NET & Azure & IoT & AI 開源技術實戰手冊 (含深入官方程式碼講解) 22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言