2016-11-10 64 views
1

我想弄清楚如何在我的Asp.Net MVC中使用C#中的異步/等待。 主要的一點似乎是,它可以幫助asp.net在您執行IO時釋放工作池中的線程(以便它們可以處理其他內容)。爲此,您必須從執行IO調用到控制器操作的方法中提升async/await修飾符(最好只有幾層)。如果您沒有將它提升到控制器,爲什麼要使用async?

使用此功能沒有任何意義,而不促進異步/等待我的控制器? (例如,在調用Async方法後添加Task.Wait)。

+0

如果你還基本上手動地做了主機系統爲異步代碼做的同樣的事情,那麼它可能是有益的,即在等待時執行其他任務。這可能相當複雜,但可行。對於異步來說真的沒有什麼魔力,它主要是一種允許頂級消費代碼做其他事情的方式,而最底層的基礎架構代碼等待某些事情完成。主機系統在頂層支持它,但代碼也是如此。但是,如果你僅僅是「遮蔽」同步操作背後的異步操作,那麼你實質上就是否定了這個好處。 – David

回答

2

答案是肯定的,但在動作中使用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完成時,它會嘗試執行線程池上下文中的其餘異步方法。該方法能夠完成,完成其返回的任務,並且沒有死鎖。如果您需要逐步將應用程序從同步轉換爲異步,此技術特別有用。

+0

如果我理解得好,我的問題的答案是「你必須推廣它」對嗎?因爲死鎖問題 –

+0

絕對是的:) –

0

請勿使用Task.Wait,因爲它可能會死鎖或產生AggregateException。如果你需要這樣做,那麼你應該使用非阻塞的Task.WhenAll

一般來說,使用端到端的異步代碼是最安全的。在整個堆棧中使用async的好處是,您的代碼將更容易調試,錯誤處理更簡單。

所以是的,如果你打算使用異步/等待 - 包括它在你的控制器,並避免使用像Task.Wait的阻止代碼。

相關問題