await
與 Task.Result
:使用方法差異及死鎖原因
在處理異步代碼時,理解 await
和 Task.Result
獲取結果值的區別至關重要。混淆兩者可能導致死鎖,尤其是在使用實現異步方法的 API 時。
考慮以下測試場景:
<code class="language-csharp">[Test] public async void CheckStatusTwiceResultTest() { Assert.IsTrue(CheckStatus().Result); // 此处挂起 Assert.IsTrue(await CheckStatus()); }</code>
在這個測試中,我們首先嘗試使用 Task.Result
從異步方法 CheckStatus
獲取結果。然而,這種方法會掛起,因為我們實際上是在執行同步等待任務完成,阻塞了執行線程。
要理解為什麼會發生這種情況,我們需要檢查 CheckStatus
方法:
<code class="language-csharp">private async Task<bool> CheckStatus() { // 进行 REST API 调用 IRestResponse<dummyservicestatus> response = await restResponse; return response.Data.SystemRunning; }</code>
此方法使用 await
進行異步 API 調用,這意味著執行會繼續進行,而無需等待響應。當我們對這個異步方法調用 Task.Result
時,它實際上會阻塞執行線程,等待結果。
由於 CheckStatus
方法本身包含異步操作(REST API 調用),嘗試通過 Task.Result
進行同步等待會造成死鎖。主執行線程正在等待 API 調用的結果,而 API 調用正在等待主線程繼續執行。
訪問異步方法結果的正確方法是使用 await
關鍵字,如下面的測試所示:
<code class="language-csharp">[Test] public async void CheckOnceAwaitTest() { Assert.IsTrue(await CheckStatus()); }</code>
在這裡,我們使用 await
來釋放執行線程,允許 API 調用異步完成。操作完成後,執行恢復,從任務中獲取結果,而不會導致死鎖。
總之,為了有效地處理異步代碼,請記住,在使用異步方法時應避免使用 Task.Result
,因為它可能導致死鎖。應改用 await
關鍵字來釋放線程並防止此類問題。
以上是``等待'vs.' task.result”:您什麼時候應該使用每種,為什麼會造成僵局?的詳細內容。更多資訊請關注PHP中文網其他相關文章!