Sdílet prostřednictvím


IHostedService Implementace 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 zaregistrované v AddHostedService<THostedService>(IServiceCollection) metodě rozšíření.

V tomto kurzu se naučíte:

  • 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í.

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.

Vytvoření služby časovače

Služba na pozadí založená na časovači využívá System.Threading.Timer třídu. Č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é

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

Je a TimerServicesealedkaskáduje DisposeAsync volání z jeho _timer instance. Další informace o "kaskádovém vzoru Dispose" naleznete v tématu Implementace DisposeAsync metody.

Při StartAsync zavolání se časovač vytvoří instance, čímž se spustí časovač.

Tip

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ží k zvýšení čítače provádění jako atomické operace, která zajišťuje, že více vláken se 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 souboru (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 .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.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: