为什么在等待后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
应该等待后解决。 对这个问题甚至有另外一个评论说明了这一点。 那么什么是真的? 它应该解决吗? 我认为不是,但我想要一个权威的答案,因为async
和await
是新的,我找不到任何明确的。
TL; DR: HttpContext.Current
在await
之后可能为null
?
请确保您正在编写一个ASP.NET 4.5应用程序,并定位到4.5。 async
和await
在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。