netcore2.1 在后台运行一个任务
在 ASP.NET Core 2.1中, 提供了一个名为BackgroundService的类,在 Microsoft.Extensions.Hosting命名空间中,其代码为
1 namespace Microsoft.Extensions.Hosting 2 { 3 // 4 // 摘要: 5 // Base class for implementing a long running Microsoft.Extensions.Hosting.IHostedService. 6 public abstract class BackgroundService : IHostedService, IDisposable 7 { 8 protected BackgroundService(); 9 10 public virtual void Dispose(); 11 // 12 // 摘要: 13 // Triggered when the application host is ready to start the service. 14 // 15 // 参数: 16 // cancellationToken: 17 // Indicates that the start process has been aborted. 18 public virtual Task StartAsync(CancellationToken cancellationToken); 19 // 20 // 摘要: 21 // Triggered when the application host is performing a graceful shutdown. 22 // 23 // 参数: 24 // cancellationToken: 25 // Indicates that the shutdown process should no longer be graceful. 26 [AsyncStateMachine(typeof(<StopAsync>d__4))] 27 public virtual Task StopAsync(CancellationToken cancellationToken); 28 // 29 // 摘要: 30 // This method is called when the Microsoft.Extensions.Hosting.IHostedService starts. 31 // The implementation should return a task that represents the lifetime of the long 32 // running operation(s) being performed. 33 // 34 // 参数: 35 // stoppingToken: 36 // Triggered when Microsoft.Extensions.Hosting.IHostedService.StopAsync(System.Threading.CancellationToken) 37 // is called. 38 // 39 // 返回结果: 40 // A System.Threading.Tasks.Task that represents the long running operations. 41 protected abstract Task ExecuteAsync(CancellationToken stoppingToken); 42 } 43 }
可以看出它是继承自 IHostedService, IDisposable , 而我们只需要继承并实现它的 ExecuteAsync 即可。
也就是说,我们只需在这个方法内写下这个服务需要做的事,
1 internal class TokenRefreshService : BackgroundService 2 { 3 private readonly ILogger _logger; 4 5 public TokenRefreshService(ILogger<TokenRefresh2Service> logger) 6 { 7 _logger = logger; 8 } 9 10 protected override async Task ExecuteAsync(CancellationToken stoppingToken) 11 { 12 _logger.LogInformation("Service starting"); 13 14 while (!stoppingToken.IsCancellationRequested) 15 { 16 _logger.LogInformation(DateTime.Now.ToLongTimeString() + ": Refresh Token!");//在此写需要执行的任务 17 await Task.Delay(5000, stoppingToken); 18 } 19 20 _logger.LogInformation("Service stopping"); 21 } 22 }
然后在Startup中注册服务。
1 // This method gets called by the runtime. Use this method to add services to the container. 2 public void ConfigureServices(IServiceCollection services) 3 { 4 services.Configure<CookiePolicyOptions>(options => 5 { 6 // This lambda determines whether user consent for non-essential cookies is needed for a given request. 7 options.CheckConsentNeeded = context => true; 8 options.MinimumSameSitePolicy = SameSiteMode.None; 9 }); 10 11 12 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 13 14 15 services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, TokenRefreshService>(); 16 17 18 19 }
注意 注意 注意
1. 当IIS上部署的项目启动后,后台任务随之启动,任务执行相应的log正常输出。
2. 手动回收对应的应用程序池,任务执行相应的log输出停止。
3. 重新请求该网站,后台任务随之启动,任务执行相应的log重新开始输出。
所以不建议在这样的后台任务中做一些需要固定定时执行的业务处理类的操作,但对于缓存刷新类的操作还是可以的,因为当应用程序池回收后再次运行的时候,后台任务会随着启动。