在 ASP.NET Core 中使用托管服务实现后台任务
在 ASP.NET Core 中,后臺任務作為托管服務實現。托管服務是一個類,具有實現 IHostedService 接口的后臺任務邏輯。
ASP.NET Core 輔助角色服務模板可作為編寫長期服務應用的起點。通過輔助角色服務模板創建的應用將在其項目文件中指定 Worker SDK:
<Project?Sdk="Microsoft.NET.Sdk.Worker">要使用該模板作為編寫托管服務應用的基礎:
創建新項目。
選擇“輔助角色服務”。選擇“下一步”。
在“項目名稱”字段提供項目名稱,或接受默認項目名稱。選擇“下一頁”。
在“其他信息”對話框中,選擇“框架” 。選擇“創建”。
Package
基于輔助角色服務模板的應用使用 Microsoft.NET.Sdk.Worker SDK,并且具有對 Microsoft.Extensions.Hosting 包的顯式包引用。有關示例,請參閱示例應用的項目文件 (BackgroundTasksSample.csproj)。
對于使用 Microsoft.NET.Sdk.Web SDK 的 Web 應用,通過共享框架隱式引用 Microsoft.Extensions.Hosting 包。在應用的項目文件中不需要顯式包引用。
IHostedService 接口
IHostedService 接口為主機托管的對象定義了兩種方法:
StartAsync(CancellationToken) StopAsync(CancellationToken)StartAsync
StartAsync 包含啟動后臺任務的邏輯。在以下操作之前調用 StartAsync:
已配置應用的請求處理管道。
已啟動服務器且已觸發 IApplicationLifetime.ApplicationStarted。可以更改默認行為,以便在配置應用的管道并調用 ApplicationStarted 之后,運行托管服務的 StartAsync。若要更改默認行為,請在調用 CreateBuilder 后添加托管服務(以下示例中的 VideosWatcher):
var?builder?=?WebApplication.CreateBuilder(args);//?Add?services?to?the?container. builder.Services.AddHostedService<VideosWatcher>();}StopAsync
StopAsync(CancellationToken) 在主機執行正常關閉時觸發。StopAsync 包含結束后臺任務的邏輯。實現 IDisposable 和終結器(析構函數)以處置任何非托管資源。
默認情況下,取消令牌會有五秒超時,以指示關閉進程不再正常。在令牌上請求取消時:
應中止應用正在執行的任何剩余后臺操作。
StopAsync 中調用的任何方法都應及時返回。
但是,在請求取消后,將不會放棄任務 — 調用方等待所有任務完成。
如果應用意外關閉(例如,應用的進程失敗),則可能不會調用 StopAsync。因此,在 StopAsync 中執行的任何方法或操作都可能不會發生。
若要延長默認值為 5 秒的關閉超時值,請設置:
ShutdownTimeout(當使用通用主機時)。有關詳細信息,請參閱 ASP.NET Core 中的 .NET 通用主機。使用 Web 主機時為關閉超時值主機配置設置。有關詳細信息,請參閱 ASP.NET Core Web 主機。托管服務在應用啟動時激活一次,在應用關閉時正常關閉。如果在執行后臺任務期間引發錯誤,即使未調用 StopAsync,也應調用 Dispose。
BackgroundService 基類
BackgroundService 是用于實現長時間運行的 IHostedService 的基類。
調用 ExecuteAsync(CancellationToken) 來運行后臺服務。實現返回一個 Task,其表示后臺服務的整個生存期。在 ExecuteAsync 變為異步(例如通過調用 await)之前,不會啟動任何其他服務。避免在 ExecuteAsync 中執行長時間的阻塞初始化工作。StopAsync(CancellationToken) 中的主機塊等待完成 ExecuteAsync。
調用 IHostedService.StopAsync 時,將觸發取消令牌。當激發取消令牌以便正常關閉服務時,ExecuteAsync 的實現應立即完成。否則,服務將在關閉超時后不正常關閉。有關更多信息,請參閱 IHostedService interface 部分。
StartAsync 應僅限于短期任務,因為托管服務是按順序運行的,在 StartAsync 運行完成之前不會啟動其他服務。長期任務應放置在 ExecuteAsync 中。有關詳細信息,請參閱 BackgroundService 數據源。
計時的后臺任務
定時后臺任務使用 System.Threading.Timer 類。計時器觸發任務的 DoWork 方法。在 StopAsync 上禁用計時器,并在 Dispose 上處置服務容器時處置計時器:
public?class?TimedHostedService?:?IHostedService,?IDisposable {private?int?executionCount?=?0;private?readonly?ILogger<TimedHostedService>?_logger;private?Timer?_timer?=?null!;public?TimedHostedService(ILogger<TimedHostedService>?logger){_logger?=?logger;}public?Task?StartAsync(CancellationToken?stoppingToken){_logger.LogInformation("Timed?Hosted?Service?running.");_timer?=?new?Timer(DoWork,?null,?TimeSpan.Zero,?TimeSpan.FromSeconds(5));return?Task.CompletedTask;}private?void?DoWork(object??state){var?count?=?Interlocked.Increment(ref?executionCount);_logger.LogInformation("Timed?Hosted?Service?is?working.?Count:?{Count}",?count);}public?Task?StopAsync(CancellationToken?stoppingToken){_logger.LogInformation("Timed?Hosted?Service?is?stopping.");_timer?.Change(Timeout.Infinite,?0);return?Task.CompletedTask;}public?void?Dispose(){_timer?.Dispose();} }Timer 不等待先前的 DoWork 執行完成,因此所介紹的方法可能并不適用于所有場景。使用 Interlocked.Increment 以原子操作的形式將執行計數器遞增,這可確保多個線程不會并行更新 executionCount。
已使用 AddHostedService 擴展方法在 IHostBuilder.ConfigureServices (Program.cs) 中注冊該服務:
services.AddHostedService<TimedHostedService>();總結
以上是生活随笔為你收集整理的在 ASP.NET Core 中使用托管服务实现后台任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信重磅更新!这个功能等了 7 年
- 下一篇: .NET 6新特性试用 | System