Sdílet prostřednictvím


IHostedService Implementujte rozhraní

Pokud potřebujete konečné řízení nad rámec poskytnutého BackgroundService, můžete implementovat vlastní IHostedService. Rozhraní IHostedService je základem pro všechny dlouhotrvající služby v .NET. Vlastní implementace jsou registrovány metodou rozšíření AddHostedService<THostedService>(IServiceCollection).

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

  • Implementujte IHostedServicerozhraní a IAsyncDisposable rozhraní.
  • Vytvořte službu založenou na časovači.
  • Zaregistrujte vlastní implementaci pomocí injektáže závislostí a protokolování.

Návod

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. 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 dotnet new worker, který vytvoří nový projekt pracovní služby v rozhraní příkazového řádku .NET CLI, najdete v tématu.

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.

Vytvoření služby časovače

Služba na pozadí založená na časovači využívá třídu System.Threading.Timer. Časovač aktivuje metodu DoWork . Časovač je zakázán IHostLifetime.StopAsync(CancellationToken) a uvolněn, když je kontejner služby uvolněn:IAsyncDisposable.DisposeAsync()

Nahraďte obsah Worker šablony následujícím kódem jazyka C# a přejmenujte soubor na TimerService.cs:

namespace App.TimerHostedService;

public sealed class TimerService(ILogger<TimerService> logger) : IHostedService, IAsyncDisposable
{
    private readonly Task _completedTask = Task.CompletedTask;
    private int _executionCount = 0;
    private Timer? _timer;

    public Task StartAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation("{Service} is running.", nameof(TimerHostedService));
        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));

        return _completedTask;
    }

    private void DoWork(object? state)
    {
        int count = Interlocked.Increment(ref _executionCount);

        logger.LogInformation(
            "{Service} is working, execution count: {Count:#,0}",
            nameof(TimerHostedService),
            count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Service} is stopping.", nameof(TimerHostedService));

        _timer?.Change(Timeout.Infinite, 0);

        return _completedTask;
    }

    public async ValueTask DisposeAsync()
    {
        if (_timer is IAsyncDisposable timer)
        {
            await timer.DisposeAsync();
        }

        _timer = null;
    }
}

Důležité

Worker byla podtřídou BackgroundService. Nyní implementuje TimerService jak IHostedServicerozhraní , tak IAsyncDisposable rozhraní.

Je to TimerService, sealed a kaskáduje volání DisposeAsync ze své instance _timer. Další informace o "kaskádovém vzoru Dispose" naleznete v tématu Implementace DisposeAsync metody.

Při zavolání StartAsync se časovač vytvoří a spustí.

Návod

Nečeká Timer na dokončení předchozích spuštění DoWork , takže zobrazený přístup nemusí být vhodný pro každý scénář. Interlocked.Increment slouží ke zvýšení čítače spuštění jako atomická operace, která zajišťuje, že více vláken neaktualizuje _executionCount souběžně.

Nahraďte existující Program obsah následujícím kódem jazyka C#:

using App.TimerHostedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<TimerService>();

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

Služba je zaregistrovaná v (Program.cs) pomocí AddHostedService metody rozšíření. Jedná se o stejnou metodu rozšíření, kterou používáte při registraci BackgroundService podtříd, protože obě implementují IHostedService rozhraní.

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

Ověření funkčnosti služby

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

info: App.TimerHostedService.TimerService[0]
      TimerHostedService is running.
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: .\timer-service
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 1
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 2
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 3
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.TimerHostedService.TimerService[0]
      TimerHostedService 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é

Existuje několik souvisejících kurzů, které je potřeba vzít v úvahu: