How to run multiple background tasks at a specific time interval?

115 Views Asked by At

I'm developing an application in C# MVC and I want to execute multiple background tasks each at different time intervals. I already have a service that inherits the class BackgroundService.

I already tried following this tutorial, but that only works if u only have 1 task.

Do you need a separate service for each task?

1

There are 1 best solutions below

4
Guru Stron On BEST ANSWER

Do you need a separate service for each task?

There are multiple options here:

  • The official documentation shows the option to create a Timed background tasks:

    public class TimedHostedService : IHostedService, IDisposable
    {
         private int executionCount = 0;
         private readonly ILogger<TimedHostedService> _logger;
         private Timer? _timer = null;
    
         public TimedHostedService(ILogger<TimedHostedService> logger)
         {
             _logger = logger;
         }
    
         public Task StartAsync(CancellationToken stoppingToken)
         {
             _logger.LogInformation("Timed Hosted Service running.");
    
             _timer = new Timer(DoWork, null, TimeSpan.Zero,
                 TimeSpan.FromSeconds(5));
    
             return Task.CompletedTask;
         }
    
         private void DoWork(object? state)
         {
             var count = Interlocked.Increment(ref executionCount);
    
             _logger.LogInformation(
                 "Timed Hosted Service is working. Count: {Count}", count);
         }
    
         public Task StopAsync(CancellationToken stoppingToken)
         {
             _logger.LogInformation("Timed Hosted Service is stopping.");
    
             _timer?.Change(Timeout.Infinite, 0);
    
             return Task.CompletedTask;
         }
    
         public void Dispose()
         {
             _timer?.Dispose();
         }
    }
    

    You can use this approach with several timers.

  • You can just start several tasks in the ExecuteAsync:

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
         await Task.WhenAll(Job1(stoppingToken), Job2(stoppingToken));
    }
    
    public async Task Job1(CancellationToken stoppingToken)
    {
         using PeriodicTimer timer = new PeriodicTimer(period1);
         while (
             !stoppingToken.IsCancellationRequested && await timer.WaitForNextTickAsync(stoppingToken))
         {
             Console.WriteLine("Work1");
         }
    }
    
    public async Task Job2(CancellationToken stoppingToken)
    {
         using PeriodicTimer timer = new PeriodicTimer(period2);
         while (
             !stoppingToken.IsCancellationRequested && await timer.WaitForNextTickAsync(stoppingToken))
         {
             Console.WriteLine("Work2");
         }
    }
    
  • Use different hosted services, one per task (personally my go to option in this case)

  • Also consider switching some scheduling libraries/frameworks like Hangfire or Quartz.NET