【问题标题】:Why is System.Web.HttpContext.Current null after awaiting an async method in a controller action?为什么在控制器操作中等待异步方法后 System.Web.HttpContext.Current 为空?
【发布时间】:2020-10-15 23:47:17
【问题描述】:

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

在我将await 添加到我的Controller 操作方法之前,这一切都有效。现在,当我随后调用使用System.Web.HttpContext.Current 的代码时,它会失败,因为HttpContext.Currentnull

我做了一些阅读,发现System.Web.HttpContext.Current 仅设置在处理 Web 请求的线程上。那讲得通。然而,令我惊讶的是,仅仅使用await 就足以切换到不同的线程。

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

我在心理上将此等同于“在同一线程上运行”——也就是说,await 之后的代码将与 await 之前的代码在同一线程上运行(即使正在等待的 Task 可能在不同的线程上执行)。事实证明这不是真的 - Thread.CurrentThread.ManagedThreadIdawait 之前和之后是不同的。

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

我很困惑 - 任何人都可以了解 (a) 在任何 await 调用之后我是否应该期望 System.Web.HttpContext.Current 为空,以及 (b) 是否有任何方法可以在 @987654348 之后生成代码@resume 在同一个线程上,所以它 not 为空?

【问题讨论】:

  • .NET Framework 还是 Core?
  • @Flydog57:.NET 框架
  • 也许这可以说明一些问题:stackoverflow.com/a/21839382/4000335
  • @kshkarin:确实支持这样的想法,即不能保证我们最终会回到同一个线程上。但是,我找到了另一个链接来解决我的具体问题 - 我会发布答案。

标签: c# asp.net-mvc async-await


【解决方案1】:

好的,我在类似的问题上找到了this answer。显然,这种行为是由 ASP.NET 的“怪癖模式”引起的。 :-(

通过确保await 之后的代码在同一线程上执行,将以下代码添加到我的web.config 解决了问题,因此HttpContext.Current 不为空。

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

【讨论】:

  • 你使用的是什么运行时?
  • @PauloMorgado:该项目最初用于 ASP.NET v4(或更早版本),现在使用 ASP.NET v4.5 或更高版本。因为项目是升级而不是重新创建的,所以 &lt;httpruntime targetFramework="4.5" /&gt; 条目没有添加到 web.config。那个或我回答中的条目都解决了我遇到的问题。
猜你喜欢
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 2017-10-08
相关资源
最近更新 更多