首页 > 解决方案 > 为什么在控制器操作中等待异步方法后 System.Web.HttpContext.Current 为空?

问题描述

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

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

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

我的理解是,使用without awaitConfigureAwait(false)如 in var result = await myTask;)可确保在.awaitSynchronizationContextawait

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

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

我很困惑 - 任何人都可以了解(a)我是否应该System.Web.HttpContext.Current在任何await调用后为空,以及(b)是否有任何方法可以await在同一线程上恢复后的代码以使其为空?

标签: c#asp.net-mvcasync-await

解决方案


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

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

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

推荐阅读