await 将 HttpContext.Current 设置为 null/prior - 无法手动设置

Posted

技术标签:

【中文标题】await 将 HttpContext.Current 设置为 null/prior - 无法手动设置【英文标题】:await sets HttpContext.Current to null/prior - cannot set it manually 【发布时间】:2015-08-06 17:57:01 【问题描述】:

如何使用手动设置的HttpContext.Current / CallContext.HostContext 进行等待恢复?当它返回到原始状态时,所有等待都会更改它(不恢复它/恢复它到其他值)。

它从哪里恢复它以及如何覆盖它?

我手动将其设置为虚拟执行页面,如果从上下文为 null 的应用程序/调度程序完成,则返回 null(如果来自另一个页面,则返回该页面)。

var wr = new System.Web.Hosting.SimpleWorkerRequest(...);
var context = new HttpContext(wr);
HttpContext.Current = context;
...
await Task.Delay(100);
// HttpContext.Current has now returned to old value / null

我尝试了各种方法,例如将 SynchronizationContext 设置为 null - 甚至强制上下文使用反射创建内部 AspNetSynchronizationContext - 但没有任何帮助。

(答案不是针对用户HttpContext.Current,也不是针对.Wait() 等使用空同步上下文)

【问题讨论】:

请问为什么需要改变上下文? @SamiKuhmonen 因为当时没有上下文(或者需要为新页面切换到新页面)+ webform 控件正在使用它 【参考方案1】:

... SynchronizationContext ...

这应该有所帮助,并且是要走的路。事实上,我能想到的唯一方法。它是await 中唯一允许您控制延续环境的挂钩。不看代码是找不到错误的。

如果您无法让内置同步上下文配合使用,您需要安装自己的同步上下文,它的行为与内置同步上下文足够相似。

HttpContext.Current 存储在某个“调用上下文”中,这是一个 .NET 概念。反编译代码看看具体存储在哪里,我忘记了。

您可能应该完全使用不同的方法。调用内部 URL 来执行您的页面,所有这些问题都会消失。不再需要做黑客了。如果这是一个高频操作,请考虑为每个虚假 HTTP 请求运行多个页面。这样可以减少开销。

【讨论】:

是的 - 谢谢,但去过那里却一无所获。不能只使用 url 执行(并且执行器也需要上下文)并使用处理程序最终会遇到同样的问题。 好吧,我不能(也没有其他人可以)在没有看到代码的情况下帮助你。你在那里犯了一个错误。一般方法有效。帮助我们帮助您并发布代码。 “充分表现”在 ASP.NET 上特别棘手。有许多帮助方法直接向下转换为AspNetSynchronizationContext,如果您使用自己的方法,则会静默失败。 ://

以上是关于await 将 HttpContext.Current 设置为 null/prior - 无法手动设置的主要内容,如果未能解决你的问题,请参考以下文章

获取客户端IP

如何在 MVC3 应用程序的 OnApplicationStarted 中获取应用程序根目录(完整物理路径)?

POST /api/Messaging/ 405(不允许的方法)

客户端浏览器在 IIS 8.0 ASP-MVC 上不断冒充管理员帐户

Log4Net - 用于 Windows 负载平衡的日志服务器 IP

将 Async/Await 与 Pickle 一起使用