In ASP.NET Core, I am using IHttpContextAccessor
to access the current HttpContext
. HttpContextAccessor
uses AsyncLocal<T>
.
In one situation, I am trying to start a Task
from within a request, that should continue running after the request has ended (long running, background task), and I am trying to detach it from the current execution context so that IHttpContextAccessor
returns null
(otherwise I am accessing an invalid HttpContext
).
I tried Task.Run
, Thread.Start
, but every time, the context seems to carry over and IHttpContextAccessor
returns the old context whatever I try (sometimes even contexts from other requests 🤔).
How can I start a task that will have a clean AsyncLocal
state so that IHttpContextAccessor
returns null
?
Late answer but might be useful for someone else. You can do this by suppressing the ExecutionContext flow as you submit your task:
ExecutionContext.SuppressFlow();
var task = Task.Run(async () => {
await LongRunningMethodAsync();
});
ExecutionContext.RestoreFlow();
or better:
using (ExecutionContext.SuppressFlow()) {
var task = Task.Run(async () => {
await LongRunningMethodAsync();
});
}
This will prevent the ExecutionContext being captured in the submitted task. Therefore it will have a 'clean' AsyncLocal state.
As above though I wouldn't do this in ASP.net if it's CPU intensive background work.
You could await the long running task and set HttpContext
to null inside await. It would be safe for all code outside the task.
[Fact]
public async Task AsyncLocalTest()
{
_accessor = new HttpContextAccessor();
_accessor.HttpContext = new DefaultHttpContext();
await LongRunningTaskAsync();
Assert.True(_accessor.HttpContext != null);
}
private async Task LongRunningTaskAsync()
{
_accessor.HttpContext = null;
}
You could run a separate thread, it doesn't matter.
Task.Run(async () => await LongRunningTaskAsync());
Just make the task awaitable to cleanup HttpContext
for the task's async context only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With