I have some tasks that require a lot of time to be executed and that I would like to run in background, so that the server can send the response to the client before the task is completed.
One working solution is the following:
public async Task<ActionResult> MyAction(){
var result = await SimpleOperation();
Task.Run(() => BackgroundOperation()); //i.e. send email
return View(result);
}
As you know, Task.Run enqueues the task in the thread pool and it will be run as soon as possible.
However Sonar Lint does not like it because Task.Run returns a Task and it is not awaited.
From .NET Core 2.1 it is possible to use BackgroundServices and shared queues to handle the execution of background Tasks:
public interface IBackgroundTaskQueue {
void Enqueue(Func<Task> taskFactory);
Task Dequeue();
bool HasItems();
}
public class MyBackgroundService : BackgroundService {
private readonly IBackgroundTaskQueue _queue;
public MyBackgroundService (IBackgroundTaskQueue queue) {
queue = _queue
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while(true)
{
if (queue.HasItems())
{
await queue.Dequeue(); //this call awaits the task to end
}
else
{
await Task.Delay(1000);
}
}
}
}
public class MyController {
private readonly IBackgroundTaskQueue _queue;
public MyController (IBackgroundTaskQueue queue) {
queue = _queue
}
public async Task<ActionResult> MyAction(){
var result = await SimpleOperation();
_queue.Enqueue(() => BackgroundOperation()); //i.e. send email
return View(result);
}
}
But this is not supported in .NET Core 1.0
What is the best solution for .NET Core 1.0? Should I use Task.Run and ignore Sonar Lint error?