译者: Akini Xu
原文: Running async tasks on app startup in ASP.NET Core 3.0
作者: Andrew Lock
此文是 探索 ASP.NET Core 3.0 第4篇:
ASP.Net Core 3.0
.csproj文件,Program.cs及通用主机ASP.Net Core 3.0
Startup.cs在不同类型项目中的差异ASP.Net Core 3.0
新特性-Service provider validationASP.Net Core 3.0
应用程序启动时运行异步任务- 介绍IHostLifetime及与通用主机间的作用关系
ASP.Net Core 3.0
新特性-启动时的结构化日志.Net Core 3.0
新特性-本地工具
在本文中,我将介绍如何在ASP.NET Core 3.0的WebHost
中做微小的改动,就能让应用程序在启动时,更方便地运行异步任务。
在程序启动时运行异步任务
在之前一个系列-应用程序启动时运行异步任务的多种方式中有过说明。 你有很多原因需要在程序启动时执行一些异步任务,例如,运行数据库迁移,验证强类型配置或填充缓存。
不幸的是,在2.x中,无法使用任何内置的ASP.NET Core语法来实现此目的:
IStartupFilter
只有同步API,因此只能通过同步调用异步方法实现。IApplicationLifetime
只有同步API,并在服务器开始处理请求后引发ApplicationStarted
事件。IHostedService
具有异步API,但只在服务器启动并开始处理请求后才执行。
对此,我提出了两种可能的解决方案:
- 在
WebHost Build
之后 ,在WebHost Run
之前,手动执行任务。 - 在服务器启动后,但接收请求之前,使用自定义
IServer
实现运行任务。 不幸的是,这种方法可能会有问题。
在ASP.NET Core 3.0中,我们仅仅对WebHost
代码进行微小的改动,就将带来很大的不同。我们不再需要上面那些解决方案,并且可以放心地使用IHostedService
。
小改动 大不同
在ASP.NET Core 2.x中,可以通过实现IHostedService
来运行后台服务。 在应用程序开始处理请求后不久(即,在Kestrel Web服务器启动之后)启动,并在应用程序关闭时停止。
在ASP.NET Core 3.0中,IHostedService
仍具有相同的目的-运行后台任务。 但是由于WebHost的微小更改,现在还可以使用它在应用程序启动时,自动运行异步任务。
在ASP.NET Core 2.x中,WebHost
的代码如下:
public class WebHost |
在ASP.NET Core 3.0中,进行了如下调整:
public class WebHost |
如您所见,IHostedService.Start
现在位于Server.StartAsync
之前执行。 这个更改意味着您现在可以使用IHostedService
运行异步任务。
在程序启动时使用IHostedService异步任务
通过实现一个IHostedService
,来作为应用程序启动任务并不是件难事。该接口包含了两个方法:
public interface IHostedService |
需要在接收请求之前运行的任何代码,都应放在StartAsync
方法中。 在这种情况下,可以忽略StopAsync方法。
例如,下面代码是在应用程序启动时,运行EF Core的迁移任务:
public class MigratorHostedService: IHostedService |
把将要运行的任务添加到依赖注入容器中,并使其在应用开始接收请求之前运行,使用AddHostedService<>()
扩展方法:
public class Startup |
被添加的后台服务会按照添加到容器中的顺序被依次执行。
总结
在本文中,介绍如何在ASP.NET Core 3.0的WebHost
中做微小的改动,就能让应用程序在启动时,更方便地运行异步任务。在ASP.NET Core 2.x中,并没有一个完美的解决办法。3.0的更改意味着可以使用IHostedService
来运行异步任务。