Sdílet prostřednictvím


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

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

V tomto kurzu se naučíte:

Tip

Všechny ukázkové zdrojové kódy Pracovních procesů v .NET jsou k dispozici v prohlížeči ukázek ke stažení. Další informace najdete v tématu Procházení ukázek kódu: Pracovní procesy 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. dotnet new Spusťte příkaz a nahraďte název požadovaného <Project.Name> projektu.

dotnet new worker --name <Project.Name>

Další informace o novém příkazu pracovního procesu rozhraní příkazového řádku .NET CLI najdete v tématu dotnet new worker.

Tip

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 , BackgroundServicevytvořte obor. 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. Definování výchozí implementace:

  • Služba je asynchronní. Metoda DoWorkAsync vrátí Taskhodnotu . Pro demonstrační účely je v DoWorkAsync metodě očekáváno zpoždění deseti sekund.
  • Vloží ILogger se do služby.:
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);
        }
    }
}

Hostovaná služba vytvoří obor, který přeloží vymezenou službu na pozadí, aby volala její DoWorkAsync metodu. DoWorkAsync vrátí hodnotu Task, která je očekávána v ExecuteAsync:

Přepsání třídy 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);

        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);
    }
}

V předchozím kódu se vytvoří explicitní obor a IScopedProcessingService implementace se vyřeší z objektu pro vytváření oboru služby injektáže závislostí. Vyřešená instance služby je vymezena a její DoWorkAsync metoda je očekávána.

Obsah souboru Program.cs šablony nahraďte 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 souboru (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 .NET.

Ověření funkčnosti služby

Pokud chcete aplikaci spustit ze sady Visual Studio, vyberte F5 nebo vyberte možnost nabídky Ladit>spuštění 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, aby vygenerovala několik přírůstků spuštění. Zobrazí se výstup podobný následujícímu:

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.

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é