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

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM