如何在具有不同计时器持续时间的 .net core 后台服务中运行多个任务

Sha*_*ggy 2 c# .net-core asp.net-core-hosted-services

我正在创建一个工作服务,它将作为 Windows 服务运行。我有一个要求,我想调用两个可能有不同计时器的任务。

SayDoWork应该每 5 分钟调用一次,并且DoAnotherWork应该每 10 分钟左右调用一次。这两个任务可以并行运行,互不依赖。

我能够创建DoWork可以每 5 分钟运行一次的任务。我对如何实现另一个具有不同计时器持续时间的任务感到有些困惑?

public class Worker : BackgroundService
{        
    private readonly IServiceScopeFactory _scopeFactory;        
    private IDataLoaderService _dataLoaderService;        

    public override Task StartAsync(CancellationToken cancellationToken)
    {
        using var scope = _scopeFactory.CreateScope();
        _dataLoaderService = scope.ServiceProvider.GetRequiredService<IDataLoaderService>();                        
        return base.StartAsync(cancellationToken);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {            
        while (!stoppingToken.IsCancellationRequested)
        {
            await DoWork(stoppingToken, _dataLoaderService);
            await Task.Delay(300000, stoppingToken); //Run every 5 minutes

            await DoAnotherWork(stoppingToken, _dataLoaderService);
            await Task.Delay(600000, stoppingToken); //Run every 10 minutes
        }
    }

    private async Task DoWork(CancellationToken stoppingToken, IDataLoaderService loaderService)
    {
        await loaderService.Process();            
    }        
    
    private async Task DoAnotherWork(CancellationToken stoppingToken, IDataLoaderService loaderService)
    {
        await loaderService.Validate();            
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 7

这两个任务可以并行运行,互不依赖。

在我看来,您有两项服务:

public class ProcessDataLoaderWorker : BackgroundService
{
  private readonly IServiceScopeFactory _scopeFactory;

  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
    using var scope = _scopeFactory.CreateScope();
    var dataLoaderService = scope.ServiceProvider.GetRequiredService<IDataLoaderService>();

    while (true)
    {
      await dataLoaderService.Process();
      await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); //Run every 5 minutes
    }
  }
}

public class ValidateDataLoaderWorker : BackgroundService
{
  private readonly IServiceScopeFactory _scopeFactory;

  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
    using var scope = _scopeFactory.CreateScope();
    var dataLoaderService = scope.ServiceProvider.GetRequiredService<IDataLoaderService>();

    while (true)
    {
      await dataLoaderService.Validate();
      await Task.Delay(TimeSpan.FromMinutes(10), stoppingToken); //Run every 10 minutes
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我还修改了 的IDataLoaderService使用方式,使其不会在其范围之外使用,并将Task.Delay参数更改为更不言自明。