托管服务
1、让代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨三点把数据导出到备份数据库,每五秒在两张表之间同步一次数据。
2、托管服务实现IHostedService接口,一般编写从BackgroundService继承的类。
3、services.AddHostedService<DemoBgService>
1 2 3 4 5 6 7 8
| public class HostedService1 : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { //在这里面执行后台代码 Console.WriteLine("后台启动"); await Task.Delay(3000); Console.WriteLine("后台代码执行完成"); } }
|
1 2
| //Program.cs builder.Services.AddHostedService<HostedService1>();
|
如果文件中发生异常:
1、程序会自动停止或退出。可以把HostOptions.BackgroundServiceExceptionBehavior设置为Ignore,程序会忽略异常,而不是停止程序,不过不推荐采用默认的设置。
2、起码应该用try…catch…包裹一下。
使用DI:
1、托管服务是以单例的生命周期注册到依赖注入容器中,因此不能注入生命周期为范围或者瞬态的服务,比如注入EFCore上下文的话,程序就会抛异常。
2、可以通过构造方法中注入一个IServiceScopeFactory,它可以用来创建一个IServiceScope对象,这样我们就可以通过IServiceScope来创建短生命周期的服务了。记得在Dispose中释放IServiceScope
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //HostedService public class HostedService1 : BackgroundService { private readonly IServiceScope serviceScope; public HostedService1(IServiceScopeFactory factory) { this.serviceScope = factory.CreateScope(); } public override void Dispose() { this.serviceScope.Dispose(); base.Dispose(); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var scopeTest = serviceScope.ServiceProvider.GetRequiredService<ScopeTest>(); scopeTest.Say(); } }
|
1 2 3
| //Progrom.cs builder.Services.AddScoped<ScopeTest>(); builder.Services.AddHostedService<HostedService1>();
|