簡體   English   中英

ASP.NET MVC中異步編程的最佳實踐是什么?

[英]What is the best practice for asynchronous programming in ASP.NET MVC?

根據這篇文章,ASP.NET要求在控制器中使用相同的SynchronizationContext進行異步操作,否則它會阻止正在運行的線程。 作為結論作者提到我們應該使用這兩種方法作為防止線程死鎖的最佳實踐:

  1. 在“庫”異步方法中,盡可能使用ConfigureAwait(false)。
  2. 不要阻止任務; 一直使用async。

    注意:最好同時應用這兩種最佳做法。 任何一個都可以防止死鎖,但兩者都必須應用以實現最大性能和響應能力。

但是什么目的導致微軟使用相同的SynchronizationContext 可能正在使用禁用相同同步上下文限制的ConfigureAwait(false)可能導致例如不可預測的行為或性能問題。 因此,在任何可能的地方使用ConfigureAwait(false)是否真的很好?

ASP.NET要求在控制器中使用相同的SynchronizationContext進行異步操作,否則它會阻止正在運行的線程。

我不太確定這個陳述是什么意思。 ASP.NET不需要“相同”的同步上下文。 為了讓你進入你的HttpContext ,你需要SynchronizationContext

但是什么目的導致微軟使用相同的SynchronizationContext

我建議你閱讀它的All About SynchronizationContext來了解有關同步上下文的更多信息。 基本上,它是一種允許您在特定線程上發布延續的機制。 例如,它可以用於將工作編組回UI應用程序內的UI消息循環線程。

可能正在使用ConfigureAwait(false),它禁用相同的同步上下文限制,可能導致例如不可預測的行為或性能問題

反之。 編組工作回到同步上下文確實具有(非常小的)開銷,因為需要將請求(使用抽象SynchronizationContext.Post )發布回所需的線程和上下文。 通過使用ConfigureAwait(false) ,您將節省該時間並繼續執行已分配線程的任何內容。

因此,在任何可能的地方使用ConfigureAwait(false)是否真的很好?

這樣做的主要原因是避免死鎖。 當有人調用Task.ResultTask.Wait而不是異步等待使用await ,你會得到經典的死鎖場景,其中同步上下文試圖將延續回發到線程上,但它當前被阻止,因為ResultWait阻塞了調用。 另一個原因是您獲得的性能開銷很小。

編輯:

為什么Microsoft不在Task類中封裝此方法? 看起來ConfigureAwait(false)只有加號。 有什么缺點嗎?

讓我們想象下面的場景:你執行一個返回一個Task的方法,等待使用await ,然后你就更新了一些UI元素。 現在,對你來說更自然的是什么? 您是否希望隱式返回到之前的相同“環境”(UI線程),或者您是否希望必須明確指定要返回到相同的環境?

我認為前者“感覺”對用戶來說更自然。

例:

public Task FetchAndReturnAsync(string url)
{
    var httpClient = new HttpClient();
    return httpClient.GetAsync(url);
}

你這樣稱呼它:

var awesomeUiResult = await FetchAndReturnAsync("http://www.google.com");
textBox.Text = awesomeUiResult;

您認為應該怎么做? 您是否更自然能夠在等待之后更新文本框,或者因為您現在不在原始上下文中而失敗?

ASP.NET要求在控制器中使用相同的SynchronizationContext進行異步操作,否則它會阻止正在運行的線程。

有點但不完全。 ASP.NET為每個傳入請求創建一個SynchronizationContext ,並且此上下文根本不依賴於特定線程。 但是,一次只有一個線程可以進入上下文,所以如果第二個線程嘗試輸入它而其中一個已經在其中,那么它將阻止該線程。

是什么目的導致微軟使用相同的SynchronizationContext?

SynchronizationContext for ASP.NET管理每個請求數據,例如HttpContext.Current ,culture和用戶身份。

在任何可能的地方使用ConfigureAwait(false)真的很好嗎?

作為一般規則,是的,特別是對於通用庫。 在ASP.NET上, ConfigureAwait(false)對您沒有多大幫助 - 在某些情況下,性能會有輕微提升。 可以用來避免我在文章中提到的死鎖,但是一直使用async要好得多(特別是在ASP.NET上)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM