So in the MSDN for ASP.Net Core it shows you how to create Background Tasks with hosted services. There is even a specific paragraph which explains how you can create a Background Queue.
Now my question is, will the ExecuteAsync method run in its own thread already, or do I need to call Task.Run first?
Will a BackgroundService always run in a new Thread? No.
BackgroundService doesn't specify anything about threading. The only thing it asks is for an overload that returns a Task, that remains active as long as the service is up. You can even return a completed task if you want.
If you check the source code you'll see that there's no assumption at all :
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
if (_executingTask.IsCompleted)
{
return _executingTask;
}
return Task.CompletedTask;
}
The threading behavior of the service method is up to the implementor, ie you. If ExecuteAsync blocks before yielding, the entire service blocks. If the method never yields, the call to StartAsync itself will block and cause problems for the entire application.
If ExecuteAsync does something expensive before the first await, starting other services will be delayed as well.
This means that you may need to use Task.Run if the service needs to do anything expensive before yielding for the first time, ie the first call to await.
will the
ExecuteAsyncmethod run in its own thread
Presuming ExecuteAsync is an async method (public async Task ExecuteAsync)
Tl;Dr it depdends
async means that this thread can be awaited. await will park the current execution of the main thread until the result of the async returns. This will release the current thread back into the thread pool for re-use. Then when the async returns a new thread (maybe depending on how you actually call this) is pulled out of the thread pool to continue execution. This is called context switching.
If this method is not truly async then nothing really happens, it run as if it's not an async method.
If this method explicitly creates a Task (using Task.Run) then the async thread will await this Task. So the Task uses a new thread and the async method will release it's thread and get a new one when the Task returns. This isn't a zero sum though as the context switching is expensive. This is why you should only async IO bound methods as you typically loose efficiency not gain in CPU bound processes.
I'd suggest you read Stephen Cleary's excellent blogs on the subject
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