2012-09-02 108 views
7

當我們在處理ASP.NET Web API中的一些可擴展點時,我們還處理TAP(基於任務的編程模式)。在某些情況下,我們希望提供一個與ContinueWith異步方法的延續,我們在委託內部執行一些內容,我們將其傳遞到ContinueWithSynchronizationContext和ASP.NET Web API可擴展性點

正如Brad Wilson深入解釋here所述,當我們提供延續時,SynchronizationContext是至關重要的。對我而言,我唯一需要回到ASP.NET Web API中的SynchronizationContext的地方是我需要使用HttpContext.Current(這是我絕對不會在ASP.NET Web API應用程序中執行的)的地方,以及我需要爲線程設置一些信息的地方,如Thread.CurrentPrincipal

所以問題是:當我們在一些可擴展性點(如消息處理程序,過濾器,格式化程序等等)中提供延續時,我們是否還想回到SynchronizationContext

回答

2

答案几乎總是

這並不是說你總是要使用同步方面,但給定的消息處理,過濾器和格式化程序的性質,你無法預測他們是否會要求使用SynchronizationContext爲了訪問HttpContextBase

即使有過濾器,在那裏你傳遞的東西,讓你訪問HttpContext(通過IActionFilter implementation說),即HttpContext是要最終看當前CallContext的線程上提供從該實例的信息。因爲當您啓動Task時,當前線程(運行異步時)沒有該信息,因此這些調用將失敗。

這就是說,如果你需要與請求關聯HttpContextBase一般,不受阻礙地進入,那麼你就絕對SynchronizationContext各地傳遞,才能進行訪問。

然而,如果可能的話,你應該複製的細節了,你所需要的HttpContextBase,並通過左右;如果你寫的東西非常普遍,那麼這是不可能的。

+0

感謝您的回答!我認爲你將問題與ASP.NET MVC混合在一起。假設您不在ASP.NET主機下。然後,你將不會有HttpContext。所以,可擴展性點與這些不緊密結合。 – tugberk

+0

@tugberk答案依然如此,真的;如果你有一些與特定上下文綁定的東西,然後想要進行異步操作,那麼你確實希望確保將這些值從上下文中複製出來(或者確保你可以訪問*到上下文中)*需要處理。 – casperOne

+0

問題在於:在Web API中,你幾乎沒有任何上下文。你可以通過線程+框架基礎架構實現的變量內的上下文總是讓你回到同步上下文,如果你看看源代碼。這就是爲什麼你的答案不適用。 – tugberk