【问题标题】:Set HttpContext.Current is not the same in continuation of await设置 HttpContext.Current 与 await 的延续不一样
【发布时间】:2021-09-16 11:53:06
【问题描述】:

来自 Stephen Cleary 的this 回答,我了解到HttpContextSynchronizationContext 一起流动。因此,给定以下代码:

    public async Task<ActionResult> Index()
    {
        var outerContext = System.Web.HttpContext.Current = new HttpContext(
            new HttpRequest(null, "http://test.com", null),
            new HttpResponse(new StreamWriter("C:/Path")));

        Console.WriteLine(outerContext.Equals(System.Web.HttpContext.Current));

        await Task.Run(
            delegate
            {
                Console.WriteLine(outerContext.Equals(System.Web.HttpContext.Current));
            });
        
        Console.WriteLine(outerContext.Equals(System.Web.HttpContext.Current));
        
        return View();
    }

我希望控制台输出是:

True
False
True

然而,实际的输出是:

True
False
False

调试后,似乎延续中的上下文设置为请求的原始上下文,即在我通过调用HttpContext.Current = ... 手动设置之前的上下文。这是什么原因?在执行await 之后的代码之前,它是否被设置为请求上下文?

【问题讨论】:

    标签: asp.net httpcontext synchronizationcontext


    【解决方案1】:

    HttpContext.Current 的值await 保存和恢复。 await 将捕获 SynchronizationContext.Current 并使用它来恢复执行。

    当请求开始时,会创建一个新的请求上下文(其中包括一个特定的HttpContext.Current 实例)。每当AspNetSynchronizationContext 在该请求上下文上恢复执行时,它会将HttpContext.Current 设置为该请求上下文的实例。

    因此,在await 之后,HttpContext.Current 将与Index 开头的实例相同,而不是您的代码分配给它的任何实例。

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 2012-04-07
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 2013-07-31
      • 1970-01-01
      • 2014-04-13
      相关资源
      最近更新 更多