【发布时间】: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.Current 是null。
我做了一些阅读,发现System.Web.HttpContext.Current 仅设置在处理 Web 请求的线程上。那讲得通。然而,令我惊讶的是,仅仅使用await 就足以切换到不同的线程。
我的理解是,使用await 而不使用ConfigureAwait(false)(如var result = await myTask;)可确保await 之后的代码在SynchronizationContext 之前使用SynchronizationContext 调用。
我在心理上将此等同于“在同一线程上运行”——也就是说,await 之后的代码将与 await 之前的代码在同一线程上运行(即使正在等待的 Task 可能在不同的线程上执行)。事实证明这不是真的 - Thread.CurrentThread.ManagedThreadId 在 await 之前和之后是不同的。
奇怪的是,我看到的行为与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