.NET 中 yield
和 await
的控制流機制
對 .NET 中 yield
和 await
關鍵字的理解,你的認識大體正確。 yield
允許迭代器區塊將控制權傳回給呼叫程式碼,並在再次呼叫迭代器時從中斷處繼續執行。 await
不僅等待被呼叫方完成,還將控制權回傳給呼叫方。當呼叫方再次 await
該方法時,執行將從中斷處恢復。
理解這些結構的關鍵在於它們的實現機制。對於 await
,它本質上等同於一個「高級回傳」。當遇到 await
表達式時,執行時會檢查任務是否已完成。如果未完成,它會指派一個委託,將方法的剩餘部分作為任務的延續執行,並傳回給呼叫方。如果任務已完成,則立即執行方法的剩餘部分。
await
的延續包含一個數字,該數字在一個查找表中標識接下來要執行的指令指標。這確保了當任務恢復時,它可以從正確的位置繼續執行。延續也儲存所有局部變數和臨時變數的值,允許方法恢復執行,就好像它從未中斷一樣。
至於運行時如何在 await
之前處理多個方法調用的問題,答案在於調用方的激活記錄及其調用的方法的激活記錄並非存儲在同一個堆疊中。相反,await
恢復的相關資訊儲存在堆上。這確保了堆疊不會被後續方法呼叫覆蓋。
如果發生未處理的異常,則會捕獲該異常並將其儲存在任務中。當取得任務的結果時,會重新拋出該異常。這種行為確保即使在存在非同步操作的情況下也能正確處理異常。
類似的原理也適用於 yield
的實作。當迭代器區塊 yield
一個值時,局部變數的狀態以及表示 MoveNext
應該在下次呼叫迭代器時恢復執行的指令的數字會被複製到堆上。這允許迭代器在 yield
點暫停執行,並在以後恢復執行而不會丟失任何狀態。
透過利用這些複雜的機制,yield
和 await
關鍵字提供了一種強大的方法來在 .NET 中實現非同步和迭代操作。它們允許在無需線程的情況下模擬並發,從而簡化程式碼並提高效能。
以上是`yield` 和 `await` 如何管理 .NET 中的控制流?的詳細內容。更多資訊請關注PHP中文網其他相關文章!