《ASP.NET Core技术内幕与项目实战》精简集-高级组件4.2:托管服务
本节内容,涉及到8.2(P265-P269),以WebApi说明为主。主要NuGet包:
一、一个简单的托管服务
//创建托管服务类 //TestBgService public class TestBgService : BackgroundService { private readonly ILogger<TestBgService> logger; public TestBgService(ILogger<TestBgService> logger) { this.logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(5000); var str1 = await File.ReadAllTextAsync("d:/1.txt"); for (int i = 0; i < 100; i++) { await Task.Delay(2000); logger.LogInformation(str1); } } } //在容器中注册托管服务 //Program.cs builder.Services.AddHostedService<TestBgService>();
代码解读:
①托管类继承BackgroundService,BackgroundService实现了IHostedService,在IHostedService基础上增加了一些任务取消等逻辑
②托管类必须实现ExecuteAsync方法,方法体中是需要在后台执行的业务逻辑
③在Program入口类中,以依赖注入方式注册托管类服务,应用启动后,执行托管类的ExecuteAsync方法。方法在后台执行,不会阻塞AspNetCore的其它程序
④托管类中可以注入其它服务,但因为托管服务以单例方式注入,所以注入托管类的服务也必须是单例的。如果要在托管类中,注入短生命周期的服务,可以通过IServiceScope的方式
⑤托管类实现了IDisposable接口,但我们是以依赖注入方式使用,框架会帮我们自动处理
二、定时导出数据托管服务
1 //创建ExportStringBgService托管类 2 //ExportStringBgService.cs 3 public class ExportStringBgService : BackgroundService 4 { 5 private readonly ILogger<ExportStringBgService> logger; 6 private readonly IServiceScope serviceScope; 7 public ExportStringBgService(IServiceScopeFactory scopeFactory) 8 { 9 serviceScope = scopeFactory.CreateScope(); 10 var sp = serviceScope.ServiceProvider; 11 this.logger = sp.GetRequiredService<ILogger<ExportStringBgService>>(); 12 } 13 14 protected override async Task ExecuteAsync(CancellationToken stoppingToken) 15 { 16 while (!stoppingToken.IsCancellationRequested) 17 { 18 try 19 { 20 StringBuilder sb = new StringBuilder(); 21 for (int i = 0; i < 100; i++) 22 { 23 sb.AppendLine($"abcdefg+{i}"); 24 } 25 await File.WriteAllTextAsync("d:/1.txt", sb.ToString()); 26 logger.LogInformation("写入成功"); 27 28 await Task.Delay(1000); 29 } 30 catch (Exception ex) 31 { 32 logger.LogError(ex, "写入字符失败"); 33 await Task.Delay(1000); 34 } 35 } 36 } 37 38 public override void Dispose() 39 { 40 base.Dispose(); 41 serviceScope.Dispose(); 42 } 43 } 44 45 46 //注册托管服务 47 //Program.cs 48 var builder = WebApplication.CreateBuilder(args); 49 builder.Services.AddHostedService<ExportStringBgService>();
代码解读:
5-12行:构造函数中注入①IServiceScopeFactory服务,通过它创建一个②范围服务serviceScope,在范围服务类,创建一个scope范围的③服务定位器ServiceProvide,通过服务定位器,注入生命周期为scope范围的服务ILogger。通过这种方式,可以在托管类中注入比单例生命周期更短的服务,比如DbContext。
38-41行:由于范围服务是我们在托管的单例生命周期中开的小窗,且serviceScope实现了IDisposable接口,需要手工Discope。
16,28行:通过while循环,持续执行后台服务。通过Task.Delay(1000),每秒钟定时执行一次。
18-34行:通过try...catch,当发生异常时,不会因为托管服务的未处理异常导致程序退出。
特别说明:
1、本系列内容主要基于杨中科老师的书籍《ASP.NET Core技术内幕与项目实战》及配套的B站视频视频教程,同时会增加极少部分的小知识点
2、本系列教程主要目的是提炼知识点,追求快准狠,以求快速复习,如果说书籍学习的效率是视频的2倍,那么“简读系列”应该做到再快3-5倍