.Net 5 实现后台定时任务
对于这个问题可以分为两步来实现,首先如何实现后台任务呢?答案是:IHostedService(了解更多传送门)
IHostedService这个接口只包含两个成员方法:Task StartAsync(CancellationToken cancellationToken); Task StopAsync(CancellationToken cancellationToken);
即应用程序启动时调用StartAsync方法开启服务,应用程序关闭时停止调用StopAsync服务
然后是如何实现定时调度呢? 方法有很多,就简单有效的办法就是Timer,干净利落且有效。下面奉上源码:
1 public abstract class ScheduledService : IHostedService, IDisposable 2 { 3 private readonly Timer _timer; 4 private readonly TimeSpan _period; 5 protected readonly ILogger Logger; 6 protected ScheduledService(TimeSpan period, ILogger logger) 7 { 8 Logger = logger; 9 _period = period; 10 _timer = new Timer(Execute, null, Timeout.Infinite, 0); 11 } 12 public void Execute(object state = null) 13 { 14 try 15 { 16 Logger.LogInformation("Begin ScheduledService service"); 17 ExecuteAsync().Wait(); 18 } 19 catch (Exception ex) 20 { 21 Logger.LogError(ex, "ScheduledService Exception"); 22 } 23 finally 24 { 25 Logger.LogInformation("ScheduledService finished"); 26 } 27 } 28 protected abstract Task ExecuteAsync(); 29 public virtual void Dispose() 30 { 31 _timer?.Dispose(); 32 GC.SuppressFinalize(this); 33 } 34 35 public Task StartAsync(CancellationToken cancellationToken) 36 { 37 Logger.LogInformation("Service is starting."); 38 _timer.Change(TimeSpan.FromSeconds(10), _period); 39 return Task.CompletedTask; 40 } 41 public Task StopAsync(CancellationToken cancellationToken) 42 { 43 Logger.LogInformation("Service is stopping."); 44 _timer?.Change(Timeout.Infinite, 0); 45 return Task.CompletedTask; 46 } 47 }
如何使用呢:定义ClearDatedFiles 类并重写ExecuteAsync方法来实现你的具体业务代码
1 public class ClearDatedFiles : ScheduledService 2 { 3 private readonly IServiceProvider _serviceProvider; 4 /// <summary> 5 /// 每10分钟执行一次 6 /// </summary> 7 /// <param name="logger"></param> 8 public ClearDatedFiles(ILogger<ClearDatedFiles> logger) : base(TimeSpan.FromMinutes(10), logger) 9 { 10 _serviceProvider = InternalApp.ServicesProvider; 11 } 12 /// <summary> 13 /// 定时任务 14 /// </summary> 15 /// <returns></returns> 16 protected override Task ExecuteAsync() 17 { 18 var service = (IClearDatedFilesService)(_serviceProvider.GetService(typeof(IClearDatedFilesService)));//IOC实例化实体 19 return service.ClearDatedFiles();//执行任务 20 } 21 }
然后在Startup中注入使用:services.AddHostedService<ClearDatedFiles>();