我想弄清楚如何在我的Asp.Net MVC中使用C#中的異步/等待。 主要的一點似乎是,它可以幫助asp.net在您執行IO時釋放工作池中的線程(以便它們可以處理其他內容)。爲此,您必須從執行IO調用到控制器操作的方法中提升async/await修飾符(最好只有幾層)。如果您沒有將它提升到控制器,爲什麼要使用async?
使用此功能沒有任何意義,而不促進異步/等待我的控制器? (例如,在調用Async方法後添加Task.Wait)。
我想弄清楚如何在我的Asp.Net MVC中使用C#中的異步/等待。 主要的一點似乎是,它可以幫助asp.net在您執行IO時釋放工作池中的線程(以便它們可以處理其他內容)。爲此,您必須從執行IO調用到控制器操作的方法中提升async/await修飾符(最好只有幾層)。如果您沒有將它提升到控制器,爲什麼要使用async?
使用此功能沒有任何意義,而不促進異步/等待我的控制器? (例如,在調用Async方法後添加Task.Wait)。
答案是肯定的,但在動作中使用Task.Wait()
不是一個好主意,因爲它可能導致死鎖情況。
考慮從引導下,Async/Await Best Practice通過Stephen Cleary:
圖3上的共同死鎖問題當異步碼阻塞
public static class DeadlockDemo { private static async Task DelayAsync() { await Task.Delay(1000); } // This method causes a deadlock when called in a GUI or ASP.NET context. public static void Test() { // Start the delay. var delayTask = DelayAsync(); // Wait for the delay to complete. delayTask.Wait(); } }
但是,如果添加ConfigureAwait(false)
到DelayAsync()
是這樣的:
await Task.Delay(1000).ConfigureAwait(false)
那麼你就可以避免死鎖,在文章中解釋說:
從性能除此之外,
ConfigureAwait
還有一個重要的方面:它可避免死鎖。考慮圖3再次;如果將「ConfigureAwait(false)
」添加到DelayAsync
中的代碼行,則可避免死鎖。這一次,當await完成時,它會嘗試執行線程池上下文中的其餘異步方法。該方法能夠完成,完成其返回的任務,並且沒有死鎖。如果您需要逐步將應用程序從同步轉換爲異步,此技術特別有用。
如果我理解得好,我的問題的答案是「你必須推廣它」對嗎?因爲死鎖問題 –
絕對是的:) –
請勿使用Task.Wait,因爲它可能會死鎖或產生AggregateException。如果你需要這樣做,那麼你應該使用非阻塞的Task.WhenAll。
一般來說,使用端到端的異步代碼是最安全的。在整個堆棧中使用async的好處是,您的代碼將更容易調試,錯誤處理更簡單。
所以是的,如果你打算使用異步/等待 - 包括它在你的控制器,並避免使用像Task.Wait的阻止代碼。
如果你還基本上手動地做了主機系統爲異步代碼做的同樣的事情,那麼它可能是有益的,即在等待時執行其他任務。這可能相當複雜,但可行。對於異步來說真的沒有什麼魔力,它主要是一種允許頂級消費代碼做其他事情的方式,而最底層的基礎架構代碼等待某些事情完成。主機系統在頂層支持它,但代碼也是如此。但是,如果你僅僅是「遮蔽」同步操作背後的異步操作,那麼你實質上就是否定了這個好處。 – David