Asp.net

Asp.net SynchronizationContext 為非同步延續鎖定 HttpApplication?

  • July 31, 2012

Stephen Cleary的評論是這樣說的:

AspNetSynchronizationContext是最奇怪的實現。它視為Post同步而不是非同步,並使用鎖一次執行一個委託

同樣,他寫的關於同步上下文並在該評論中連結到的文章表明:

從概念上講,AspNetSynchronizationContext 的上下文是複雜的。在非同步頁面的生命週期中,上下文僅從 ASP.NET 執行緒池中的一個執行緒開始。非同步請求啟動後,上下文不包含任何執行緒。當非同步請求完成時,執行其完成常式的執行緒池執行緒進入上下文。這些可能是發起請求的相同執行緒,但更有可能是在操作完成時碰巧空閒的任何執行緒。

如果同一應用程序一次完成多個操作,AspNetSynchronizationContext 將確保它們一次執行一個。它們可以在任何執行緒上執行,但該執行緒將具有原始頁面的身份和文化。

探勘反射器似乎可以驗證這一點,因為它HttpApplication在呼叫任何回調時會鎖定。

鎖定應用程序對像似乎很可怕。所以我的第一個問題是:這是否意味著今天,整個應用程序的所有非同步完成都一次執行一個,即使是源自具有單獨 HttpContext 的單獨執行緒上的單獨請求的那些?對於任何 100% 使用非同步頁面(或 MVC 中的非同步控制器)的應用程序來說,這不是一個巨大的瓶頸嗎?如果不是,為什麼不呢?我錯過了什麼?

此外,在 .NET 4.5 中,似乎有一個新AspNetSynchronizationContext的,舊的被重命名LegacyAspNetSynchronizationContext,並且僅在UseTaskFriendlySynchronizationContext未設置新的應用程序設置時使用。所以問題 #2:新的實現會改變這種行為嗎?否則,我想隨著新的 async/await 支持通過同步上下文封送完成,這種瓶頸會更頻繁地被注意到。

這個論壇文章的答案(從這裡的 SO 答案連結)表明這裡發生了根本性的變化,但我想弄清楚那是什麼以及哪些行為得到了改進,因為我們有一個 .NET 4 MVC 3 應用程序,它幾乎100% 非同步操作方法進行 Web 服務呼叫。

讓我回答你的第一個問題。在您的假設中,您沒有考慮單獨的 ASP.NET 請求由不同的 HttpApplication 對象處理的事實。HttpApplication 對象儲存在池中。一旦您請求一個頁面,就會從池中檢索一個應用程序對象,並在請求完成之前屬於該請求。所以,我對你的問題的回答:

整個應用程序的所有非同步完成都一次執行一個,即使是源自具有單獨 HttpContext 的單獨執行緒上的單獨請求的完成

是:不,他們沒有

單獨的請求由單獨的 HttpApplication 對象處理,鎖定的 HttpApplication 只會影響單個請求。同步上下文是一個強大的東西,它可以幫助開發人員同步對共享(在請求範圍內)資源的訪問。這就是為什麼所有回調都在鎖定下執行的原因。同步上下文是基於事件的同步模式的核心。

引用自:https://stackoverflow.com/questions/11369614