前言:在本文中,我將介紹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
您可能要這樣作的緣由有不少-例如,運行數據庫遷移,驗證強類型配置或填充緩存。不幸的是,在2.x中,不可能使用任何內置的ASP.NET Core原語來實現此目的:ide
相反,我提出了兩種可能的解決方案:oop
使用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運行異步任務。
假設您要延遲應用程序處理請求,直到異步任務完成爲止。 若是不是這種狀況,您可能要使用本系列最後一篇文章中的運行情況檢查方法。
咱們能夠經過實現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/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。