Sdílet prostřednictvím


Použití vymezených služeb v rámci BackgroundService

Když zaregistrujete implementace IHostedService použitím některé z AddHostedService metod rozšíření, služba se zaregistruje jako singleton. Můžou existovat scénáře, ve kterých byste se chtěli spolehnout na službu s vymezeným oborem. Další informace naleznete v tématu Injektáž závislostí v .NET: Životnost služby.

V tomto návodu se naučíte, jak:

Návod

Zdrojový kód "Pracovní procesy v .NET" je k dispozici v prohlížeči ukázek ke stažení. Další informace najdete v tématu Prohlédněte si ukázky kódu: pracovníky v .NET.

Požadavky

Vytvoření nového projektu

Pokud chcete vytvořit nový projekt Služby pracovního procesu pomocí sady Visual Studio, vyberte Soubor>Nový projekt>.... V dialogovém okně Vytvořit nový projekt vyhledejte "Pracovní služba" a vyberte šablonu pracovní služby. Pokud raději použijete .NET CLI, otevřete svůj oblíbený terminál v pracovním adresáři. Spusťte příkaz dotnet new a nahraďte <Project.Name> názvem požadovaného projektu.

dotnet new worker --name <Project.Name>

Další informace o příkazu projektu nové pracovní služby .NET CLI najdete viz dotnet new worker.

Návod

Pokud používáte Visual Studio Code, můžete z integrovaného terminálu spustit příkazy .NET CLI. Další informace naleznete v tématu Visual Studio Code: Integrovaný terminál.

Vytváření služeb s vymezeným oborem

Pokud chcete použít vymezené služby v rámci BackgroundService, vytvořte obor pomocí rozhraní IServiceScopeFactory.CreateScope() API. Pro hostované služby se ve výchozím nastavení nevytvořil žádný obor. Služba na pozadí s vymezeným oborem obsahuje logiku úlohy na pozadí.

namespace App.ScopedService;

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

Předchozí rozhraní definuje jednu DoWorkAsync metodu. Vytvořte implementaci v nové třídě s názvem 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;
    }
}
  • Pomocí primárního konstruktoru se do služby vloží ILogger.
  • Metoda DoWorkAsync vrátí Task a přijme CancellationToken.
    • Metoda zaznamenává identifikátor instance—_instanceId je přiřazen při každém instancování třídy.

Přepište třídu Worker

Nahraďte existující Worker třídu následujícím kódem jazyka C# a přejmenujte soubor na 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);
    }
}

V předchozím kódu se sice stoppingToken nezruší, ale IServiceScopeFactory slouží k vytvoření oboru. Od IServiceScope je IScopedProcessingService vyřešen. Metoda DoWorkAsync je očekávána a stoppingToken je předána metodě. Nakonec se provedení zpozdí o 10 sekund a smyčka pokračuje. Při každém zavolání metody DoWorkAsync se vytvoří nová instance DefaultScopedProcessingService a zaprotokoluje se identifikátor instance.

Nahraďte obsah souboru šablony Program.cs následujícím kódem jazyka C#:

using App.ScopedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();

IHost host = builder.Build();
host.Run();

Služby jsou zaregistrované v (Program.cs). Hostovaná služba je zaregistrovaná v AddHostedService metodě rozšíření.

Další informace o registraci služeb naleznete v tématu Injektáž závislostí v rozhraní .NET.

Ověření funkčnosti služby

Chcete-li aplikaci spustit ze sady Visual Studio, vyberte F5 nebo možnost nabídky Ladit>Spustit ladění. Pokud používáte .NET CLI, spusťte dotnet run příkaz z pracovního adresáře:

dotnet run

Další informace o příkazu pro spuštění .NET CLI najdete v tématu dotnet run.

Nechte aplikaci běžet po určitou dobu a vygenerujte několik volání DoWorkAsync, čímž se zaznamenají nové identifikátory instance. Zobrazí se výstup podobný následujícím protokolům:

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.

Pokud aplikaci spouštíte ze sady Visual Studio, vyberte Ladění>zastavit ladění.... Případně můžete výběrem kláves Ctrl + C z okna konzoly signalizovat zrušení.

Viz také