探索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 ...
随机推荐
- django--调用百度AI接口实现人脸注册登录
面部识别----考勤打卡.注册登录.面部支付等等...感觉很高大上,又很方便,下面用python中的框架--django完成一个注册登录的功能,调用百度AI的接口,面部识别在网上也有好多教程,可以自己 ...
- css的伪元素 ::after ::before 和 图标字体的使用
浅谈css的伪元素::after和::before css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁.但是很多人对::after和 ...
- Leetcode练习题 Palindrome Number
9. Palindrome Number Question: Determine whether an integer is a palindrome. An integer is a palindr ...
- sqoop的详细使用及原理
转自:https://blog.csdn.net/zhusiqing6/article/details/95680185 1.sqoop简介sqoop是一个用来将hadoop中hdfs和关系型数据库中 ...
- 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)
[洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...
- Kafka生产消费API JAVA实现
Maven依赖: <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka- ...
- 简单解决 VMWare “无法打开内核设备:\\Global\\vmx86”错误
在“服务”后右击选择使用管理员打开.然后在一大串服务中找到vm开头的服务项,全部都启动.重新启动vm就ok了(vm需要以管理员身份打开).
- vue-路由-显示名称
显示名称 方式1: <div id="app"> <!-- 分析: --> <!-- 1. 我们要监听到 文本框数据的改变,这样才能知道 什么时候去拼 ...
- Python3中13个实例汇总
1.Python数字求和 # -*- codingLuft-8 -*- #Filename: test.py #author by:Leq #用户输入数字 num1 = input("输入第 ...
- JAVA----HelloWorld
1.步骤 将java代码编写到扩展名为.java的文件中(扩展名的查看) 新建文本文档,重命名为Test.java. 以记事本方式打开. 写入代码. public class Test{ ...