探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的应用中启动时运行异步任务
前言:在本文中,我将介绍ASP.NET Core 3.0 WebHost的微小更改如何使使用IHostedService在应用程序启动时更轻松地运行异步任务。
翻译 :Andrew Lock https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-3/
探索ASP.NET Core 3.0系列一:新的项目文件、Program.cs和generic host
探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cs
探索 ASP.Net Core 3.0系列三:ASP.Net Core 3.0中的Service provider validation
探索 ASP.Net Core 3.0系列五:引入IHostLifetime并弄清Generic Host启动交互
探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志
一、在应用启动时运行异步任务
您可能要这样做的原因有很多-例如,运行数据库迁移,验证强类型配置或填充缓存。不幸的是,在2.x中,不可能使用任何内置的ASP.NET Core原语来实现此目的:
- IStartupFilter具有同步API,因此需要通过异步进行同步。
- IApplicationLifetime具有同步API,并在服务器开始处理请求后触发ApplicationStarted事件。
- IHostedService具有异步API,但是在服务器启动并开始处理请求之后执行。
相反,我提出了两种可能的解决方案:
- 在构建WebHost之后但在运行之前手动执行任务。
- 在服务器启动接收请求之前,使用自定义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
{
public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{
// ... initial setup
await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false); // Fire IApplicationLifetime.Started
_applicationLifetime?.NotifyStarted(); // Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false); // ...remaining setup
}
}
ASP.Net Core 3.0中的变化如下:
public class WebHost
{
public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{
// ... initial setup // Fire IHostedService.Start
await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false); // ... more setup
await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false); // Fire IApplicationLifetime.Started
_applicationLifetime?.NotifyStarted(); // ...remaining setup
}
}
如您所见,IHostedService.Start现在在Server.StartAsync之前执行。 此更改意味着您现在可以使用IHostedService运行异步任务。
假设您要延迟应用程序处理请求,直到异步任务完成为止。 如果不是这种情况,您可能要使用本系列最后一篇文章中的运行状况检查方法。
二、在应用启动时使用IHostedService 运行一个异步任务
我们可以通过实现IHostedService 来创建一个任务,这个接口就包含两个 方法:
public interface IHostedService
{
Task StartAsync(CancellationToken cancellationToken);
Task StopAsync(CancellationToken cancellationToken);
}
您想要在接收请求之前运行的任何代码都应放在StartAsync方法中。 在这种情况下,可以忽略StopAsync方法。
例如,以下启动任务在应用程序启动时异步运行EF Core迁移:
public class MigratorHostedService: IHostedService
{
// We need to inject the IServiceProvider so we can create
// the scoped service, MyDbContext
private readonly IServiceProvider _serviceProvider;
public MigratorHostedService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
} public async Task StartAsync(CancellationToken cancellationToken)
{
// Create a new scope to retrieve scoped services
using(var scope = _serviceProvider.CreateScope())
{
// Get the DbContext instance
var myDbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>(); //Do the migration asynchronously
await myDbContext.Database.MigrateAsync();
}
} // noop
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
要将任务添加到依赖项注入容器中,并使其在应用开始接收请求之前运行,请使用AddHostedService <>扩展方法:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// other DI configuration
services.AddHostedService<MigratorHostedService>();
} public void Configure(IApplicationBuilder)
{
// ...middleware configuration
}
}
这些服务将在启动时按照添加到DI容器中的顺序执行,即稍后在ConfigureServices中添加的服务将在启动后执行。
三、总结
在本文中,我描述了ASP.NET Core 3.0中WebHost的微小更改如何使您能够在应用程序启动时更轻松地运行异步任务。 在ASP.NET Core 2.x中,没有一个理想的选择,但是3.0的更改意味着可以使用IHostedService来履行该角色。
翻译 :Andrew Lock https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-3/
作者:郭峥
出处:http://www.cnblogs.com/runningsmallguo/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的应用中启动时运行异步任务的更多相关文章
- 如何在ASP.NET Core程序启动时运行异步任务(1)
原文:Running async tasks on app startup in ASP.NET Core (Part 1) 作者:Andrew Lock 译者:Lamond Lu 背景 当我们做项目 ...
- 如何在ASP.NET Core程序启动时运行异步任务(2)
原文:Running async tasks on app startup in ASP.NET Core (Part 2) 作者:Andrew Lock 译者:Lamond Lu 在我的上一篇博客中 ...
- ASP.NET Core 3.x启动时运行异步任务(一)
这是一个大的题目,需要用几篇文章来说清楚.这是第一篇. 一.前言 在我们的项目中,有时候我们需要在应用程序启动前执行一些一次性的逻辑.比方说:验证配置的正确性.填充缓存.或者运行数据库清理/迁移等 ...
- 如何在ASP.NET Core程序启动时运行异步任务(3)
原文:Running async tasks on app startup in ASP.NET Core (Part 3) 作者:Andrew Lock 译者:Lamond Lu 之前我写了两篇有关 ...
- ASP.NET Core 3.x启动时运行异步任务(二)
这一篇是接着前一篇在写的.如果没有看过前一篇文章,建议先去看一下前一篇,这儿是传送门 一.前言 前一篇文章,我们从应用启动时异步运行任务开始,说到了必要性,也说到了几种解决方法,及各自的优缺点.最 ...
- 探索 ASP.Net Core 3.0系列三:ASP.Net Core 3.0中的Service provider validation
前言:在本文中,我将描述ASP.NET Core 3.0中新的“validate on build”功能. 这可以用来检测您的DI service provider是否配置错误. 具体而言,该功能可检 ...
- 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志
前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...
- 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
C#中的函数式编程:递归与纯函数(二) 在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...
随机推荐
- PHP 构造函数
在PHP5以前的版本中,构造函数的名称必须与类名相同,这种方法在PHP5中仍然可以使用,但现在已经很少有人用了.PHP5以及之后的版本,构造函数用__construct()方法来声明,这样做的好处是可 ...
- path()函数
path()函数具有以下四个参数 route 必须 view 必须 kwargs 可选 name 可选 route route是一个匹配URL的准则(类似正则表达式) 当Django响应一个请求时,它 ...
- SQLServer临时库文件太大,迁移tempdb数据库
问题描述: 最近公司这边tempdb库文件很大,几百GB的节奏 不过安装数据库的时候,tempdb最好不要放在C盘是放在D盘其他数据盘的 如果没有放在其他盘符下面,就需要做迁移了 解决方法: 如果te ...
- Java Serializable:明明就一个空的接口嘛
对于 Java 的序列化,我一直停留在最浅显的认知上——把那个要序列化的类实现 Serializbale 接口就可以了.我不愿意做更深入的研究,因为会用就行了嘛. 但随着时间的推移,见到 Serial ...
- CSP-S 爆零记
抱歉,这么晚才更. 事实是:我都没有去 所以爆零了 QwQ
- .net core入门-跨域访问配置
Asp.net Core 跨域配置 一般情况WebApi都是跨域请求,没有设置跨域一般会报以下错误 No 'Access-Control-Allow-Origin' header is prese ...
- 这篇文章带你彻底理解synchronized
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...
- Flask笔记:信号机制
Flask中有内置的一些信号,也可以通过三方库blinker自定义信号,其实Flask内置的信号也是优先使用的blinker库,如果没有安装blinker才会使用自定义的信号机制.可以通过点击任意导入 ...
- [20191011]bash任意进制编码表.txt
[20191011]bash任意进制编码表.txt --//bash可以使用任意进制编码转化为十进制.我想了解内部编码:--//实际上受字符集的限制,"任意"进制有限制的.测试看看 ...
- 1.JavaCC安装与测试
下面介绍的是JavaCC在windows系统中的安装与小代码测试过程. 一.JavaCC安装 步骤 :在JavaCC的官网首页下载JavaCC,然后配置电脑的环境变量,接着在dos命令行里就可 ...