I am using ASP.NET Core 3.1, and I need to find a way to run a background task/thread/timer which is not connected to the current HttpContext.
For instance, consider the following code:
public class MyController : ApiControllerBase
{
private readonly IHttpContextAccessor _contextAccessor;
public MyController(IHttpContextAccessor contextAccessor)
{
this._contextAccessor = contextAccessor;
}
[HttpGet]
public IActionResult DoSomething()
{
// Start a task on another thread.
Task.Run(this.TaskAction);
// Start a background thread.
var thread = new Thread(this.ThreadAction);
thread.IsBackground = true;
thread.Start();
thread.Join();
// Start a timer.
var timer = new System.Timers.Timer();
timer.Interval = 1;
timer.Elapsed += this.Timer_Elapsed;
timer.AutoReset = false;
timer.Start();
Thread.Sleep(3000);
return this.StatusCode(200);
}
private void TaskAction()
{
if (this._contextAccessor.HttpContext != null)
Debug.WriteLine("Oh no! We have an HttpContext in the task action");
}
private void ThreadAction() {
if (this._contextAccessor.HttpContext != null)
Debug.WriteLine("Oh no! We have an HttpContext in the thread action");
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (this._contextAccessor.HttpContext != null)
Debug.WriteLine("Oh no! We have an HttpContext in the timer action");
}
}
My problem is that in each of these background operations, the HttpContext
is there. However, in certain cases (because the background operations are long-running tasks and due to the current application architecture), we must have no context in place in the new threads. That's the way things worked in .NET Framework.
My question is: what is the correct way to accomplish this? I want all my background operations to have NO HTTP context.
The only way I've found at the moment is to temporarily suspend the thread execution context flow when creating the background task. For example:
// Start a task on another thread.
using (var flowContext = ExecutionContext.SuppressFlow())
{
Task.Run(this.TaskAction);
}
Is this ok, or am I going to screw myself over somehow?