2013-08-22 97 views
69

我有以下測試的WebAPI的代碼,我沒有在生產中使用的WebAPI,但我做了,因爲討論中,我對這個問題的:WebAPI Async question爲什麼在等待後HttpContext.Current爲null?

不管怎麼說,這裏是違規的WebAPI方法:

public async Task<string> Get(int id) 
{ 
    var x = HttpContext.Current; 
    if (x == null) 
    { 
     // not thrown 
     throw new ArgumentException("HttpContext.Current is null"); 
    } 

    await Task.Run(() => { Task.Delay(500); id = 3; }); 

    x = HttpContext.Current; 
    if (x == null) 
    { 
     // thrown 
     throw new ArgumentException("HttpContext.Current is null"); 
    } 

    return "value"; 
} 

我曾經相信第二個異常是可以預料到的,因爲當await完成時,它可能會在不同的線程中,作爲線程靜態變量的HttpContext.Current將不再解析爲適當的值。現在,基於同步上下文,它可能實際上被迫在等待之後回到同一個線程,但我在測試中沒有做任何事情。這只是await的簡單而天真的使用。

在另一個問題的意見,我被告知HttpContext.Current應該等待後解決。關於這個問題甚至有另一個評論表明相同。那麼,什麼是真的?它應該解決嗎?我認爲不是,但我想要一個權威的答案,因爲asyncawait是新的,我找不到任何明確的。

TL; DR:是HttpContext.Current潛在null之後await

+2

你的問題不清楚 - 你說過你會發生什麼,評論表明那*是*發生了什麼......所以你有什麼困惑? –

+0

@ user2674389,這是誤導。它是'AspNetSynchronizationContext',負責'HttpContext',而不是'await'。更多的,'await'的繼續回調可能(也很可能會)發生在Web API執行模型的不同線程上。編輯爲 – Noseratio

+0

以提供簡潔的問題 – welegan

回答

110

請確保您正在編寫一個ASP.NET 4.5應用程序和目標4.5。 asyncawait在ASP.NET上有未定義的行爲,除非您正在運行4.5 正在使用新的「任務友好」同步上下文。

具體而言,這意味着你必須:

  • 設置httpRuntime.targetFramework4.5,或
  • 在你appSettings,設置aspnet:UseTaskFriendlySynchronizationContexttrue

更多的信息是available here

+0

我絕對在.NET 4.5上 – welegan

+2

我剛剛創建了一個新的ASP.NET 4.5 WebAPI項目,複製/粘貼了你的代碼並做了測試。它對我來說非常合適(沒有拋出異常)。請重新檢查您是否正在運行*並定位* 4.5。 –

+2

我有目標框架:.NET Framework 4.5集。我不知道該告訴你什麼,在我的本地機器上肯定是空的。 – welegan

2

是我測試的有缺陷的,或者是有一些的web.config元素,我在這裏失去了 這將使HttpContext.Current正確解析 等待後?

您的測試是不是有缺陷的,當你等待,這將確保遵循這個等待代碼傳遞正確的HttpContext,這是HttpContext.Current不應該是的await後無效,因爲的ASP.NET Web API在等待之前呈現。

+0

您確定關於WebAPI的相同延續線程嗎?我處理了[case](http://stackoverflow.com/q/18284998/1768303),它是一個不同的線程。 – Noseratio

+4

ASP.NET將在任何線程池線程上恢復,但具有正確的請求上下文。 –

+2

是的,你是對的,線程可能不一樣,但HttpContext.Current將與await之前的一樣。我更新了我的問題。 –

16

由於@StephenCleary正確地指出的那樣,你需要在這你的web.config:

<httpRuntime targetFramework="4.5" /> 

當我第一次解決此,我做了上述的解決方案範圍內的搜索,證實了它的存在所有我的網站項目,並迅速將其視爲罪魁禍首。最終我想到了在全文中查看那些搜索結果:

<!-- 
    For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367. 

    The following attributes can be set on the <httpRuntime> tag. 
    <system.Web> 
     <httpRuntime targetFramework="4.5" /> 
    </system.Web> 
--> 

Doh。

課程:如果將Web項目升級到4.5,您仍然需要手動設置該設置。

+14

另一個問題是這是不同於<編譯目標框架「4.5」/> – Andrew

+0

謝謝。 @安德魯 – Barry