在
當你使用任何AddHostedService擴充方法註冊IHostedService的實作時,該服務會被註冊為單例。 在某些情況下,您可能需要依賴於特定範圍內的服務。 欲了解更多資訊,請參閱服役壽命。
在本教學課程中,您將瞭解如何:
- 正確解析單例 BackgroundService 中的具有範圍的相依性。
- 將工作委派給具範圍的服務。
- 實施
override於BackgroundService.StopAsync(CancellationToken)。
小提示
所有 「.NET 工作者」範例原始程式碼都可在 範例瀏覽器 下載。 如需詳細資訊,請參閱 瀏覽程式碼範例:.NET 中的工作者。
先決條件
- .NET 8.0 SDK 或更新版本
- .NET 整合開發環境(IDE),例如 Visual Studio
建立新專案
若要使用 Visual Studio 建立新的背景工作服務專案,請選取 [檔案]>[新增>專案...]。從 [[建立新專案] 對話框搜尋 [背景工作服務],然後選取 [背景工作服務] 範本。 如果您想要使用 .NET CLI,請在工作目錄中開啟您最愛的終端機。 執行 dotnet new 命令,並將 <Project.Name> 取代為您所需的項目名稱。
dotnet new worker --name <Project.Name>
如需 .NET CLI 新工作服務專案命令的詳細資訊,請參閱 dotnet new worker。
小提示
如果您使用 Visual Studio Code,您可以從整合式終端機執行 .NET CLI 命令。 如需詳細資訊,請參閱 Visual Studio Code:整合式終端機。
建立具有限定範圍的服務
若要在 中使用 BackgroundService,請使用 IServiceScopeFactory.CreateScope() API 建立一個範圍。 根據預設,不會針對託管服務建立任何範圍。 限定範圍的背景服務包含背景工作的邏輯。
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
以上介面定義了一個單一方法DoWorkAsync。 在名為 DefaultScopedProcessingService.cs 的新類別中建立實作:
namespace App.ScopedService;
public sealed class DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
private readonly string _instanceId = Guid.NewGuid().ToString();
public Task DoWorkAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{ServiceName} doing work, instance ID: {Id}",
nameof(DefaultScopedProcessingService),
_instanceId);
return Task.CompletedTask;
}
}
- 使用主要建構函式將 ILogger 插入服務中。
-
DoWorkAsync方法會傳回Task並接受 CancellationToken。- 方法會記錄實體識別碼,每當類別被實例化時,
_instanceId就會被指派。
- 方法會記錄實體識別碼,每當類別被實例化時,
重寫 Worker 類別
以下列 C# 程式代碼取代現有的 Worker 類別,並將檔案重新命名為 ScopedBackgroundService.cs:
namespace App.ScopedService;
public sealed class ScopedBackgroundService(
IServiceScopeFactory serviceScopeFactory,
ILogger<ScopedBackgroundService> logger) : BackgroundService
{
private const string ClassName = nameof(ScopedBackgroundService);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is running.", ClassName);
while (!stoppingToken.IsCancellationRequested)
{
using IServiceScope scope = serviceScopeFactory.CreateScope();
IScopedProcessingService scopedProcessingService =
scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
await Task.Delay(10_000, stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is stopping.", ClassName);
await base.StopAsync(stoppingToken);
}
}
在上述程式代碼中,當 stoppingToken 未取消時,IServiceScopeFactory 被用來建立範圍。 從IServiceScope中解析IScopedProcessingService。 方法 DoWorkAsync 會等候,且 stoppingToken 會傳遞至 方法。 最後,執行會延遲 10 秒,循環會繼續執行。 每次呼叫 DoWorkAsync 方法時,會建立 DefaultScopedProcessingService 的新實例,並記錄實例的標識符。
使用下列 C# 程式代碼取代樣本 Program.cs 檔案內容:
using App.ScopedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();
IHost host = builder.Build();
host.Run();
這些服務會在 (Program.cs) 中註冊。 托管服務會使用 AddHostedService 擴充方法註冊。
如需註冊服務的詳細資訊,請參閱 .NET 中的相依性插入 。
驗證服務功能
若要從 Visual Studio 執行應用程式,請選取 F5 或選取 [>偵錯開始偵錯] 功能表選項。 如果您使用 .NET CLI,請從工作目錄執行 dotnet run 命令:
dotnet run
如需 .NET CLI 執行命令的詳細資訊,請參閱 dotnet run。
讓應用程式執行一段時間來產生數個對 DoWorkAsync 的呼叫,因此會記錄新的實例識別碼。 您會看到類似下列記錄的輸出:
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\scoped-service
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is stopping.
如果從 Visual Studio 執行應用程式,可選擇偵錯[>停止偵錯...]。亦可透過控制台視窗按下 Ctrl + C 發出取消訊號。