我建议使用已有的针对定时后台任务的解决方案,比如Hangfire。
在类似于你的场景中,我倾向于注册一个单独的SchedulerService来控制那些需要按照计划或每隔一定时间间隔启动的任务,例如每分钟运行一次任务,就像你所描述的情况。
以下是我项目中的一个示例:
public class MyBackgroundService(IServiceProvider serviceProvider) : BackgroundService
{
private bool _isFirstRun = true;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var scope = serviceProvider.CreateScope();
// 我们只需一次性注册所有任务
if (_isFirstRun)
{
var worker = scope.ServiceProvider.GetRequiredService<ISchedulerWorker>();
worker.Start();
_isFirstRun = false;
}
}
}
在此实现简单的调度器工作者,在这里你可以调用所需的方法
public class SchedulerWorker(IRepository repository) : ISchedulerWorker
{
public void Start()
{
// 注册所有你需要运行的任务
RecurringJob.AddOrUpdate(nameof(TakeFreshDataAsync), () => TakeFreshDataAsync(), Cron.Minutely);
}
public async Task TakeFreshDataAsync() => await repository.TakeFreshDataAsync();
}
并在Program.cs中进行所有服务的注册:
services.AddScoped<ISchedulerWorker, SchedulerWorker>();
services.AddScoped<IRepository, Repository>();
services.AddHostedService<MyBackgroundService>();
// 生产环境中不推荐使用MemoryStorage,你可以选择其他存储提供者
services.AddHangfire(config => { config.UseMemoryStorage(); });
``