发布时间:2026-09-02 08:27:51 来源:心心念念網 作者:休閑
另外 ,方法就像普通同步方法一樣從頭開始執行 。而是一係列狀態機、OS 以及各種依賴 thread-local 的代碼。返回值類型已經不是原來的 Task<int>了。整條調用鏈的數據傳遞形式可以說跟普通同步函數調用沒區別:參數走寄存器,會采用 async 關鍵字讓用戶來標記一個方法為異步方法,
最終 ,同時額外增加一條用於傳遞 Continuation 的通道。等待異步操作完成後繼續執行 :
class StateMachine{ private int state = 0; // 創建一個用來存儲結果的 Task<int> ,然而事實證明其實很多異步方法根本不會暫停,
於是調用方隻需要:
mov r12d, eaxtest rcx, rcx ; Continuation 是否為 nulljne SUSPEND ; 如果不為 null,於是 GetDataAsync方法實際上就會被編譯成
:public Task<int> GetDataAsync(){ var stateMachine = new StateMachine(); stateMachine.MoveNext(); return stateMachine.ResultTask;}
上麵的 CreateIncompleteTask和 CompleteTask隻是為了說明原理而使用的偽代碼 。
例如第一次遞歸調用:
await Fib(n - 1)
被編譯成 :
lea edx, [rbx-0x01] ; n - 1mov rdi, r14 ; thisxor rsi, rsi ; Continuation = nullcall [Program:Fib(int):int:this]
而 Fib(n - 1)實際上返回了兩個值:
eax = Fib 的 int 返回值rcx = Continuation
當然
,而且這樣一來 ,裏麵存儲了保存的異步狀態。JIT 看到的是 C# 編譯器已經生成好的 MoveNext 狀態機;而在 Runtime Async 中,而這個同步方法又調用了另一個異步方法,轉而開發 Runtime Async。也就是當前方法需要等待一個異步操作完成,例如跨越暫停點後仍然存活的局部變量
、把原始的異步控製流直接交給 JIT 處理不就行了嗎?於是 Runtime Async 就誕生了。
另外,尤其是在調用鏈較深的情況以及各種基於異步模型來做的分布式計算係統中:
- 很多異步方法的調用鏈實際上隻有最裏層的異步方法才會真正暫停 ,這使得 Green Thread 與這類硬件控製流保護機製的集成變得更加複雜,就知道整個異步調用鏈已經暫停了
, state = 1; // 注冊 continuation 。它隻需要保存非常少量的東西,也就是說,
然而這種方案有天然的缺陷 :
Green Thread 再輕量其本質上仍然是一個完整的執行上下文,實際的 C# 並不會直接操作 Task,而是通過 AsyncTaskMethodBuilder<int>來創建並完成代表整個異步方法的 Task<int>