Search code examples
c#.nettaskbackground-service.net-3.0

How to run multiple tasks on a background service?


I am trying to run 3 task simultaneously but they are waiting for each other to finish. For example, second task is waiting for first one, and the third one is waiting for second task to finish.

I want all 3 tasks to start at the same time.

IStatusProcess.cs

public interface IStatusProcess
    {
        Task GetSystemStatus();
        Task GetProcessesWithError();
        Task GetNumberofProcessesInLastDay();
    }

    public class StatusProcess : IStatusProcess
    {
        public async Task GetSystemStatus()
        {
            logger.LogInformation("Getsystemstatus - - -");
            await Task.Delay(1* 1000);
        }
        public async Task GetProcessesWithError()
        {
            logger.LogInformation("Get proceesses with error - - -");

            await Task.Delay(5* 1000);
        }
        public async Task GetNumberofProcessesInLastDay()
        {
            logger.LogInformation("Get Processes in last day - - -");

            await Task.Delay(10* 1000);
        }
}

Worker.cs

 public class StatusWorker : BackgroundService
    {
        private readonly IStatusProcess statusProcess;
        private readonly ILogger<StatusWorker> logger;

        public StatusWorker(IStatusProcess statusProcess, ILogger<StatusWorker> logger)
        {
            this.statusProcess = statusProcess;
            this.logger = logger;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is how we keep the app running (in the background)
            while (!stoppingToken.IsCancellationRequested)
            {
                logger.LogInformation("StatusWorker running at: {time}",
                    DateTimeOffset.Now);
                await statusProcess.GetSystemStatus();
                await statusProcess.GetProcessesWithError();
                await statusProcess.GetNumberofProcessesInLastDay();
            }
        }
    }

Solution

  • That's because you "await" each task to finish before starting the next. This could be correct if you really need the output of a process to be consumed by the next task, but you want to run them parallel. WhenAll should do the trick:

    Task.WhenAll(
        statusProcess.GetSystemStatus, 
        statusProcess.GetProcessesWithError,
        statusProcess.GetNumberofProcessesInLastDay);
    

    For instance see this: Running async methods in parallel or google parallel async tasks.