Home > Back-end >  Set HttpContext.Current is not the same in continuation of await
Set HttpContext.Current is not the same in continuation of await

Time:09-21

From this answer from Stephen Cleary, I understand that the HttpContext flows with the SynchronizationContext. Therefore, given the following piece of code:

    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();
    }

I would expect the console output to be:

True
False
True

However, the actual output is:

True
False
False

After debugging, it appears that the context in the continuation is set to the original context of the request, the one it had before I manually set it by calling HttpContext.Current = .... What is the reason for this? Does it get set to the request context somewhere before the code after the await gets executed?

CodePudding user response:

The HttpContext.Current value is not saved and restored by await. await will capture SynchronizationContext.Current and use that to resume execution.

When the request starts, a new request context is created (which includes a specific HttpContext.Current instance). Whenever AspNetSynchronizationContext resumes execution on that request context, it sets HttpContext.Current to the instance for that request context.

So, after the await, HttpContext.Current will be the same instance it was at the beginning of Index, not whatever instance your code assigns to it.

  • Related