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?
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.