BackgroundService 中使用限定範圍的服務

當您使用任何 IHostedService 擴充方法註冊 AddHostedService 實作時 - 服務會註冊為單一資料庫。 在部分情況下,您可能會想要依賴限定範圍的服務。 如需詳細資訊,請參閱在 .NET 中插入相依性:服務存留期

在本教學課程中,您會了解如何:

提示

範例瀏覽器中提供所有「.NET 中的背景工作角色」範例原始程式碼以供下載。 如需詳細資訊,請參閱瀏覽程式碼範例:.NET 中的背景工作角色

必要條件

建立新專案

若要使用 Visual Studio Code 建立新的背景工作服務專案,您將選取 [檔案]>[新增]>[專案...]。從 [建立新專案] 對話方塊搜尋 [背景工作服務],然後選取 [背景工作服務] 範本。 如果您想要使用 .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 內使用限定範圍服務,請建立一個範圍。 根據預設,不會針對託管服務建立任何範圍。 限定範圍的背景服務包含背景工作的邏輯。

namespace App.ScopedService;

public interface IScopedProcessingService
{
    Task DoWorkAsync(CancellationToken stoppingToken);
}

上述介面會定義單一 DoWorkAsync 方法。 若要定義預設實作:

  • 服務為非同步。 DoWorkAsync 方法會傳回 Task。 基於示範用途,在 DoWorkAsync 方法中需等候延遲十秒。
  • ILogger 會插入服務中:
namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private int _executionCount;

    public async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            ++ _executionCount;

            logger.LogInformation(
                "{ServiceName} working, execution count: {Count}",
                nameof(DefaultScopedProcessingService),
                _executionCount);

            await Task.Delay(10_000, stoppingToken);
        }
    }
}

託管服務會建立範圍來解析範圍背景工作服務,以呼叫其 DoWorkAsync 方法。 DoWorkAsync 會傳回在 ExecuteAsync 中等待的 Task

重寫背景工作角色類別

以下列 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);

        await DoWorkAsync(stoppingToken);
    }

    private async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is working.", ClassName);

        using (IServiceScope scope = serviceScopeFactory.CreateScope())
        {
            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is stopping.", ClassName);

        await base.StopAsync(stoppingToken);
    }
}

在上述程式碼中,會建立明確的範圍,並利用相依性插入服務範圍處理站解析 IScopedProcessingService 實作。 已解析的服務執行個體已設定範圍,並等候其 DoWorkAsync 方法。

使用下列 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

讓應用程式執行一段時間以產生數個執行計數增量。 您會看到類似下方的輸出:

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is working.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 1
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 working, execution count: 2
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

如果從 Visual Studio 內執行應用程式,請選取 [偵錯]>[停止偵錯...]。或者,從主控台視窗選取 Ctrl + C 以發出取消訊號。

另請參閱