为什么在等待后HttpContext.Current为空?

我有以下testingWebAPI代码,我没有在生产中使用WebAPI,但是由于我在这个问题上的讨论,我做了这个: WebAPIasynchronous问题

无论如何,这是有问题的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"; } 

我曾经相信,第二个exception是预料之中的,因为当await完成时,它可能会在不同的线程, HttpContext.Current作为线程静态variables将不再parsing为适当的值。 现在,基于同步上下文,在等待之后,实际上可能会被迫回到同一个线程,但是我在testing中没有做任何事情。 这只是一个简单,天真的使用await

在另一个问题的意见,我被告知HttpContext.Current应该等待后解决。 对这个问题甚至有另外一个评论说明了这一点。 那么什么是真的? 它应该解决吗? 我认为不是,但我想要一个权威的答案,因为asyncawait是新的,我找不到任何明确的。

TL; DR: HttpContext.Currentawait之后可能为null

请确保您正在编写一个ASP.NET 4.5应用程序,并定位到4.5。 asyncawait在ASP.NET上有未定义的行为,除非你在4.5上运行, 并且正在使用新的“任务友好”同步上下文。

特别是,这意味着您必须:

  • httpRuntime.targetFramework设置为4.5 ,或者
  • 在你的appSettings ,将aspnet:UseTaskFriendlySynchronizationContext设置为true

更多信息可以在这里find 。

正如@StephenCleary正确地指出,你需要在你的web.config中:

 <httpRuntime targetFramework="4.5" /> 

当我第一次解决这个问题时,我在上面search了一个解决scheme,确认它出现在我的所有Web项目中,并迅速将其作为罪魁祸首。 最终我想到了全面的search结果:

 <!-- 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> --> 

卫生署。

课程:如果将Web项目升级到4.5,则仍然需要手动进行设置。

我的testing是否有缺陷,或者是否有一些web.config元素我在这里失踪,这将使HttpContext.Current在等待后正确parsing?

您的testing没有缺陷,并且在等待之后HttpContext.Current不应该为空,因为在ASP.NET Web API中,当您等待时,这将确保在此之后的代码传递在await之前存在的正确的HttpContext。