• 探索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/

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

  • 相关阅读:
    C语言结构体中的函数指针与函数
    写博客
    图灵C/C++图书阅读路线图
    c语言预处理
    Gnu gprof
    linux下全目录全文搜索强大工具grep
    openssl源代码结构
    js学习笔记——脚本化浏览器窗口
    js学习笔记——js的功能限制
    js学习笔记——在html中嵌入脚本
  • 原文地址:https://www.cnblogs.com/runningsmallguo/p/11617238.html
Copyright © 2020-2023  润新知