共用方式為


BackgroundService中使用的範疇服務

當你使用任何AddHostedService擴充方法註冊IHostedService的實作時,該服務會被註冊為單例。 在某些情況下,您可能需要依賴於特定範圍內的服務。 欲了解更多資訊,請參閱服役壽命。

在本教學課程中,您將瞭解如何:

小提示

所有 「.NET 工作者」範例原始程式碼都可在 範例瀏覽器 下載。 如需詳細資訊,請參閱 瀏覽程式碼範例:.NET 中的工作者

先決條件

建立新專案

若要使用 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 發出取消訊號。

另請參閱