3.5 注册多个托管服务,通过定义的 BackManagerService 任务调度器,我们甚至具备了同时托管数个任务的能力,而我们只需要在 ConfigureServices 增加一行代码
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, BackManagerService>(factory => { OrderManagerService order = new OrderManagerService(); return new BackManagerService(options => { options.Name = "订单超时检查"; options.CheckTime = 5 * 1000; options.Callback = order.CheckOrder; options.Handler = order.OnBackHandler; }); }); services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, BackManagerService>(factory => { OrderManagerService order = new OrderManagerService(); return new BackManagerService(options => { options.Name = "成交数量统计"; options.CheckTime = 2 * 1000; options.Callback = order.CheckOrder; options.Handler = order.OnBackHandler; }); }); }3.6 为了方便,我们还是使用 OrderManagerService 来模拟业务,只是把任务名称改成 "成交数量统计",并设置任务执行周期间隔为 2 秒
3.7 现在来运行程序,观察输出
3.8 输出结果正常,两个托管服务独立运行,互不干扰,蓝色为 "成交数量统计",白色为 "订单超时检查"
结语得益于 .Net Core 提供的轻量型主机 IHostedService,我们可以方便的把后台任务注册到托管主机中,托管主机随着宿主进程的启动和退出执行相关的业务逻辑,这点非常重要,由于这种人性化的设计,我们可以在宿主进程启动和退出的时候去做一些业务级别的工作。
值得注意的是,IHostedService 中的方法 StartAsync 会在服务启动的时候马上执行,这可能导致宿主进程并未完全初始化业务数据,导致托管任务报错,所以我们采用了延迟启动,即在 StartAsync 内部使用代码阻止任务立即执行
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 延迟启动 await Task.Delay(this.options.CheckTime, stoppingToken); ... }在默认情况下, CancellationToken 令牌取消的超时时间为 5 秒,如果你希望留更多的时间给业务处理,可以通过下面的代码修改,比如本示例设置为 15 秒后超时
public static void Main(string[] args) { CreateWebHostBuilder(args) .UseShutdownTimeout(TimeSpan.FromSeconds(15)) .Build().Run(); }本次行文略显罗嗦,代码量也稍大了一些,主要是希望大家可以去理解原理后,使用起来心里比较有底一些
示例代码下载https://files.cnblogs.com/files/viter/Ron.BackHost.zip