首页 > 解决方案 > 在 ASP.NET 4.8 中等待后 HttpContext 为空

问题描述

我正在尝试在 asp.net 4.8 中编写异步代码,但问题是从等待返回后 HttpContext 为空。这意味着异步代码可以正常工作,这很好,但原始代码需要 HttpContext。从Darin Dimitrov的以下回答中的评论可以看出,HttpContext 自4.6.1 以来就存在此问题。 为什么 HttpContext.Current 在等待之后为空?

var domains = HttpContext.Current.Cache.Get("domains") as Dictionary<String, Domains>;


            if (domains == null)
            {
                var x = await TrackingMethods.GetTableForCacheAsync().ConfigureAwait(false);
                domains = x.domains;
        }

/// HttpContext.Current is null here

标签: asp.net

解决方案


ConfigureAwait(false) 表示“不要在捕获的上下文中恢复”。通过指定ConfigureAwait(false),您的代码告诉运行时它不需要 ASP.NET 请求上下文。但是您的代码确实需要 ASP.NET 请求上下文,因为它依赖于HttpContext.Current. 所以ConfigureAwait(false)在这里使用是错误的。

如果我不使用 ConfigureAwait(false) 代码将不会运行。

这可能是因为您的代码进一步阻塞了调用堆栈,从而导致了 deadlock。理想的解决方案是移除阻塞- 即,async一直使用. 一直使用比使用async阻塞更可取ConfigureAwait(false)

但是,在少数情况下这是不可能的。例如,ASP.NET 4.8 对 MVC 操作筛选器或子操作没有适当的异步支持。如果你正在做这样的事情,那么你有几个选择:

  • 让它一直同步而不是一直异步。
  • 保留blocking-over-async-with- ConfigureAwait(false)antipattern,但首先复制代码需要的所有内容HttpContext.Current,并将该数据作为显式参数传递,这样代码就不再依赖于ASP.NET请求上下文。

推荐阅读