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.