Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Workers to run parallel-ly in .NET core

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.

like image 588
Vnkt-esh Avatar asked Oct 25 '25 07:10

Vnkt-esh


1 Answers

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);
  }
});
like image 75
Stephen Cleary Avatar answered Oct 26 '25 22:10

Stephen Cleary



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!