I have created a Worker Service project in .NET Core with the intention of 3 independent workers. All these 3 workers should run parallel-ly and independent of other workers. And this worker service as a whole will be running as a Windows Service.
In the main Program.cs, I have registered the 3 workers as below:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
IConfiguration configuration = hostContext.Configuration;
services.AddHostedService<WorkerA>();
services.AddHostedService<WorkerB>();
services.AddHostedService<WorkerC>();
});
}
Each worker code will be as follows, doing their intended job:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
WorkerA_DoWork();
await Task.Delay(6000, stoppingToken);
}
}
Problem Statement: When I execute the project, I am facing few issues like, when WorkerA() doesn't have any process to run, WorkerB() (or) WorkerC() do not start their work. I think it is basically waiting for WorkerA() to do something before WorkerB() or WorkerC() can start doing their work.
Please advise how can they work independently i.e.: each workers should not wait for other worker and should run independently.
When I execute the project, I am facing few issues like, when WorkerA() doesn't have any process to run, WorkerB() (or) WorkerC() do not start their work. I think it is basically waiting for WorkerA() to do something before WorkerB() or WorkerC() can start doing their work.
.NET Core allows any number of hosted services; however, it starts executing them serially. So the problem with this code:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
WorkerA_DoWork();
await Task.Delay(6000, stoppingToken);
}
}
is that WorkerA_DoWork is synchronous. I.e., it's synchronously waiting for work to do.
The solution can be one of two things. Either make the "get next work item" method asynchronous:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await WorkerA_DoWorkAsync();
await Task.Delay(6000, stoppingToken);
}
}
or wrap the entire ExecuteAsync inside a Task.Run:
protected override Task ExecuteAsync(CancellationToken stoppingToken) => Task.Run(async () =>
{
while (!stoppingToken.IsCancellationRequested)
{
WorkerA_DoWork();
await Task.Delay(6000, stoppingToken);
}
});
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