我正在用C#MVC开发一个应用程序,我希望在不同的时间间隔执行多个后台任务.我已经有了一个继承类BackEarth Service的服务.

I already tried following this tutorial,但只有当你只有一项任务时才有效.

您是否需要 for each 任务提供单独的服务?

推荐答案

您是否需要 for each 任务提供单独的服务?

这里有多个选项:

  • 官方文档显示了创建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();
         }
    }
    

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

  • 您可以只启动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

Csharp相关问答推荐

无法使用并行库并行化我的代码

ASP.NET Core -是否可以对所有最小API端点应用过滤器?

使用C#中的Shape API从Azure目录获取所有用户

总是丢弃返回的任务和使方法puc无效之间有区别吗?

向类注入一个工厂来创建一些资源是一个好的实践吗?

有没有一种方法可以防止在编译时在MicrosoftC或非单线程上下文中调用方法?

数组被内部函数租用时,如何将数组返回给ArrayPool?

为什么Blazor值在更改后没有立即呈现?

是否可以使用EF—Core进行临时部分更新?

MAUI查询参数单一字符串项将不起作用

有没有办法在WPF文本框中添加复制事件的处理程序?

如何在不考虑年份的情况下判断日期时间是否在某个日期范围内?

Quartz调度程序不调用作业(job)类

是否由DI容器自动处理由ActivatorUilties.CreateInstance()创建的服务?

CRL已过期,但ChainStatus告诉我RevocationStatus未知

EF Core 7-忽略模型绑定中的虚拟属性

FakeItEasy自动嘲弄内容

如何在ASP.NET Core 8中获取键控服务词典

C#中COM对象的实际地址

将列表转换为带有逗号分隔字符串形式的值的字典