如何以特定时间间隔运行多个后台任务?

问题描述 投票:0回答:1

我正在使用 C# MVC 开发一个应用程序,我想以不同的时间间隔执行多个后台任务。我已经有一个继承BackgroundService类的服务。

我已经尝试按照本教程进行操作,但只有当你只有 1 个任务时才有效。

您是否需要为每项任务提供单独的服务?

c# asp.net asp.net-mvc background-service background-task
1个回答
0
投票

您是否需要为每项任务提供单独的服务?

这里有多个选项:

  • 官方文档显示了创建定时后台任务的选项:

    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();
         }
    }
    

您可以将此方法与多个计时器一起使用。

  • 您可以在

    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");
         }
    }
    
  • 使用不同的托管服务,每个任务一个(在这种情况下我个人会选择)

  • 还可以考虑切换一些调度库/框架,例如HangfireQuartz.NET

© www.soinside.com 2019 - 2024. All rights reserved.