C# 为什么System.Web.HttpContext.Current在等待控制器操作中的异步方法后为空?

C# 为什么System.Web.HttpContext.Current在等待控制器操作中的异步方法后为空?,c#,asp.net-mvc,async-await,C#,Asp.net Mvc,Async Await,在我的ASP.NET MVC web应用程序中,我的一个Controller操作方法调用一些依赖于从当前HttpContext获取信息的代码。该代码不是我的控制器的一部分,因此它不能使用控制器.HttpContext——而是使用系统.Web.HttpContext.Current。(我知道这是个坏主意,但我无法改变这一点) 在我将等待添加到我的控制器操作方法之前,这一切都是有效的。现在,当我随后调用使用System.Web.HttpContext.Current的代码时,它失败了,因为HttpC

在我的ASP.NET MVC web应用程序中,我的一个
Controller
操作方法调用一些依赖于从当前
HttpContext
获取信息的代码。该代码不是我的
控制器的一部分,因此它不能使用
控制器.HttpContext
——而是使用
系统.Web.HttpContext.Current
。(我知道这是个坏主意,但我无法改变这一点)

在我将
等待
添加到我的
控制器
操作方法之前,这一切都是有效的。现在,当我随后调用使用
System.Web.HttpContext.Current
的代码时,它失败了,因为
HttpContext.Current
null

我读了一些书,发现
System.Web.HttpContext.Current
只在处理Web请求的线程上设置。这是有道理的。然而,我很惊讶,仅仅使用
wait
就足以切换到不同的线程

我的理解是,使用
await
而不使用
ConfigureAwait(false)
(如
var result=await myTask;
)可以确保使用
await
之前有效的
SynchronizationContext
调用
await
后面的代码

我把这等同于“在同一个线程上运行”——也就是说,
await
之后的代码将与
await
之前的代码在同一个线程上运行(即使等待的
任务可能在不同的线程上执行)。事实证明并非如此,
Thread.CurrentThread.ManagedThreadId
wait
之前和之后是不同的

奇怪的是,我看到的行为与中描述的相反

我很困惑——有谁能解释一下:(a)我是否应该期望
System.Web.HttpContext.Current
在任何
wait
调用后为空,以及(b)是否有任何方法使
wait
后的代码在同一线程上恢复,使其不为空?

好,我发现了一个类似的问题。显然,这种行为是由ASP.NET的“怪癖模式”造成的:-(

将以下内容添加到我的
web.config
中,通过确保
wait
之后的代码在同一线程上执行,从而解决了该问题,因此
HttpContext.Current
为非空

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>


.NET Framework还是Core?@Flydog57:.NET Framework也许这可以说明一些问题:@kshkarin:The确实支持这样一种观点,即不能保证我们最终会回到同一个线程上。但是我找到了另一个解决我具体问题的链接-我将发布一个答案。您使用的是什么运行时?@PauloMorgado:该项目最初用于ASP.NET v4(或更早版本),现在正在使用ASP.NET v4.5或更高版本。由于项目是升级的,而不是重新创建的,
条目没有添加到web.config中。该条目或我的答案中的条目都解决了我遇到的问题。