對於這個問題可以分為兩步來實現,首先如何實現后台任務呢?答案是: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>();