前言:在本文中,我将介绍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的应用中启动时运行异步任务的更多相关文章

  1. 如何在ASP.NET Core程序启动时运行异步任务(1)

    原文:Running async tasks on app startup in ASP.NET Core (Part 1) 作者:Andrew Lock 译者:Lamond Lu 背景 当我们做项目 ...

  2. 如何在ASP.NET Core程序启动时运行异步任务(2)

    原文:Running async tasks on app startup in ASP.NET Core (Part 2) 作者:Andrew Lock 译者:Lamond Lu 在我的上一篇博客中 ...

  3. ASP.NET Core 3.x启动时运行异步任务(一)

    这是一个大的题目,需要用几篇文章来说清楚.这是第一篇.   一.前言 在我们的项目中,有时候我们需要在应用程序启动前执行一些一次性的逻辑.比方说:验证配置的正确性.填充缓存.或者运行数据库清理/迁移等 ...

  4. 如何在ASP.NET Core程序启动时运行异步任务(3)

    原文:Running async tasks on app startup in ASP.NET Core (Part 3) 作者:Andrew Lock 译者:Lamond Lu 之前我写了两篇有关 ...

  5. ASP.NET Core 3.x启动时运行异步任务(二)

    这一篇是接着前一篇在写的.如果没有看过前一篇文章,建议先去看一下前一篇,这儿是传送门   一.前言 前一篇文章,我们从应用启动时异步运行任务开始,说到了必要性,也说到了几种解决方法,及各自的优缺点.最 ...

  6. 探索 ASP.Net Core 3.0系列三:ASP.Net Core 3.0中的Service provider validation

    前言:在本文中,我将描述ASP.NET Core 3.0中新的“validate on build”功能. 这可以用来检测您的DI service provider是否配置错误. 具体而言,该功能可检 ...

  7. 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志

    前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...

  8. 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    C#中的函数式编程:递归与纯函数(二)   在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...

随机推荐

  1. flask--数据库迁移之连环踩坑记

    flask数据库迁移命令: python manage.py db init python manage.py db migrate python manage.py db upgrade 1.报错: ...

  2. Shell脚本中的while getopts用法小结

    getpots是Shell命令行参数解析工具,旨在从Shell Script的命令行当中解析参数.getopts被Shell程序用来分析位置参数,option包含需要被识别的选项字符,如果这里的字符后 ...

  3. WPF自定义控件之图片控件 AsyncImage

    AsyncImage 是一个封装完善,使用简便,功能齐全的WPF图片控件,比直接使用Image相对来说更加方便,但它的内部仍然使用Image承载图像,只不过在其基础上进行了一次完善成熟的封装 Asyn ...

  4. 关于Spring Boot你不得不知道的事--Spring Boot的基本操作

    1 Pom文件 1.1 spring-boot-starter-parent 表示当前pom文件从spring-boot-starter-parent继承下来,在spring-boot-starter ...

  5. 【转载】不可不知的 Android strings.xml 那些事

    相信 strings.xml 已经是大家在 Android 开发中最熟悉的文件之一了,但其实它也有很多需要注意的地方和一些小技巧,知道了这些可以让你的 Android 应用更加规范易用,大家来看看吧. ...

  6. ADB常用命令(adb常用命令)

    基本用法 命令语法 adb 命令的基本语法如下: adb [-d|-e|-s <serialNumber>] <command> 如果只有一个设备/模拟器连接时,可以省略掉 [ ...

  7. INSTALL_FAILED_TEST_ONLY

    查看博客:http://www.enjoytoday.cn/posts/159 Android studio安装apk无法安装,报错误,网上搜索可以看到都说是:* 调用者不被允许测试的测试程序*,但具 ...

  8. MySQL中日期和时间类型

    1 日期类型 MySql中关于日期的类型有Date/Datetime/Timestamp三种类型. 日期赋值时,允许"不严格"语法:任何标点符都可以用做日期部分或时间部分之间的间割 ...

  9. apicloud含有微信支付。支付宝支付和苹果内购的代码

    apicloud含有微信支付.支付宝支付和苹果内购的代码 <!DOCTYPE html> <html> <head> <meta charset=" ...

  10. 渗透测试学习 二十二、getshell总结

    大纲   管理员权限拿shell 普通权限拿shell 常见cms拿shell 进后台主要是可以对网站前台的内容,样式等做操作,要改脚本的内容的权限只有在webshell的权限下才可以(某些情况除外) ...