探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的应用中启动时运行异步任务

前言:在本文中,我将介绍ASP.NET Core 3.0 WebHost的微小更改如何使使用IHostedService在应用程序启动时更轻松地运行异步任务。html

 翻译 :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 validationapp

探索 ASP.Net Core 3.0系列五:引入IHostLifetime并弄清Generic Host启动交互异步

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

1、在应用启动时运行异步任务

您可能要这样作的缘由有不少-例如,运行数据库迁移,验证强类型配置或填充缓存。不幸的是,在2.x中,不可能使用任何内置的ASP.NET Core原语来实现此目的:ide

  • IStartupFilter具备同步API,所以须要经过异步进行同步。
  • IApplicationLifetime具备同步API,并在服务器开始处理请求后触发ApplicationStarted事件。
  • IHostedService具备异步API,可是在服务器启动并开始处理请求以后执行。

相反,我提出了两种可能的解决方案:oop

  • 在构建WebHost以后但在运行以前手动执行任务。
  • 在服务器启动接收请求以前,使用自定义IServer实如今服务器启动时运行任务。 不幸的是,这种方法可能会有问题。

使用ASP.NET Core 3.0,对WebHost代码进行小的更改将带来很大的不一样-咱们再也不须要这些解决方案,而且可使用IHostedService而无需担忧!ui

 

在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运行异步任务。

假设您要延迟应用程序处理请求,直到异步任务完成为止。 若是不是这种状况,您可能要使用本系列最后一篇文章中的运行情况检查方法。

 

2、在应用启动时使用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中添加的服务将在启动后执行。

 

 

3、总结

在本文中,我描述了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/

本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章
相关标签/搜索