I'm working with Net6 and Worker process (not asp.net). I need to have two or more backgroundservices running in parallel in the same worker process.
I do that with Task.Run(()=>...)
but I don't know if it is a good practice and I would ask to you what do you think about it.
So I create a new Worker project with two hostedServices:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services
.AddHostedService<Worker>()
.AddHostedService<Worker2>();
});
Backgroundservice Worker implementation:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
for (int i = 0; i < 1000; i++)
{
if (stoppingToken.IsCancellationRequested) break;
Console.WriteLine($"Worker1 - {i}");
}
}
Worker2:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
for (int i = 0; i < 1000; i++)
{
if (stoppingToken.IsCancellationRequested) break;
Console.WriteLine($"Worker2 - {i}");
}
}
I'll got as result
Worker1 - 1
Worker1 - 2
...
Worker1 - 999
Worker2 - 1
Worker2 - 2
...
Worker2 - 999
So the task Worker2 is executed after the Worker.
If I use Task.Run inside each ExecuteAsync:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Run(() =>
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
for (int i = 0; i < 1000; i++)
{
if (stoppingToken.IsCancellationRequested) break;
Console.WriteLine($"Worker1 - {i}");
}
});
}
and
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Run(() =>
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
for (int i = 0; i < 1000; i++)
{
if (stoppingToken.IsCancellationRequested) break;
Console.WriteLine($"Worker1 - {i}");
}
});
}
The output is
Worker1 - 1
Worker2 - 1
Worker2 - 2
Worker1 - 1
...
Which to me is good but I'm asking to you if it is a good practice to use Task.Run to parallelize the two backgroundservices.
Somewhere I read something about it is a good practice avoid Task.Run. What else should I use then?
Thank you.
I do that with Task.Run(()=>...) but I don't know if it is a good practice and I would ask to you what do you think about it.
Using Task.Run
is normal because ExecuteAsync
will otherwise block the host startup, as I describe on my blog.
They are planning to fix this behavior in .NET 7.0, probably by just having BackgroundService
run ExecuteAsync
within a Task.Run
so everyone else doesn't have to do it.