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
- Sada .NET 8.0 SDK nebo novější
- Integrované vývojové prostředí .NET (IDE)
- Neváhejte používat Visual Studio
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 TimerService
sealed
kaská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: