【发布时间】:2017-09-20 23:51:23
【问题描述】:
我有一个面向 .NET 4.6 的 ASP.NET 应用程序,我正在疯狂地试图弄清楚为什么 HttpContext.Current 在我的异步 MVC 控制器操作中的第一次等待之后变为空。
我已经检查并三重检查了我的项目的目标是 v4.6,并且 web.config 的 targetFramework 属性也是 4.6。
SynchronizationContext.Current 在 await 之前和之后都分配,它是正确的,即 AspNetSynchronizationContext,而不是旧的。
FWIW,有问题的 await 确实会在继续时切换线程,这可能是因为它调用了外部 I/O 绑定代码(异步数据库调用),但这不应该是问题,AFAIU。
然而,确实如此! HttpContext.Current 变为 null 的事实给我的代码带来了许多问题,这对我来说没有任何意义。
我检查了the usual recommendations,我很肯定我正在做我应该做的一切。我的代码中也绝对没有ConfigureAwait!
我拥有的是我的 HttpApplication 实例上的几个异步事件处理程序:
public MvcApplication()
{
var helper = new EventHandlerTaskAsyncHelper(Application_PreRequestHandlerExecuteAsync);
AddOnPreRequestHandlerExecuteAsync(helper.BeginEventHandler, helper.EndEventHandler);
helper = new EventHandlerTaskAsyncHelper(Application_PostRequestHandlerExecuteAsync);
AddOnPostRequestHandlerExecuteAsync(helper.BeginEventHandler, helper.EndEventHandler);
}
我需要这两个,因为自定义授权和清理逻辑需要异步。 AFAIU,这是受支持的,应该不是问题。
我看到的这种令人费解的行为还有什么可能的原因?
更新:补充观察。
SynchronizationContext 引用在 await 之后与 await 之前保持不变。但它的内部结构在两者之间发生了变化,如下面的截图所示!
目前我不确定这与我的问题有什么关系(或什至是否)。希望别人能看到!
【问题讨论】:
-
您是否在控制器操作上调用
ConfigureAwait(false)? -
@Paulo:不,我不是。
-
@Eldho:那有什么意义呢?我需要并且想要控制器操作上的异步,正是因为内部(即我提到的数据库调用,作为一个例子)是异步的。删除异步需要我禁用大量代码。
-
@Eldho 如何在没有
async的情况下测试async特有的问题?测试会显示什么?那在单线程非异步代码中HttpContext.Current不会失去价值?我已经很确定是这样的。 -
@Eldho:我不确定我是否跟随,抱歉。您是在谈论删除控制器方法上的 async 修饰符并摆脱主体中的等待吗?如果是这样,那么我不知道如何。我需要等待任务,因为我需要在返回最终的 ActionResult 之前对其值做一些事情。任务和 ActionResult 没有直接联系。因此,如果没有需要测试的等待,恐怕我真的无法做任何有用的事情。
标签: c# asp.net async-await