IHostedService
Implementera gränssnittet
När du behöver begränsad kontroll utöver den angivna BackgroundServicekan du implementera din egen IHostedService. Gränssnittet IHostedService är grunden för alla långvariga tjänster i .NET. Anpassade implementeringar registreras med AddHostedService<THostedService>(IServiceCollection) tilläggsmetoden.
I den här självstudien lär du dig att:
- Implementera - och-gränssnittenIHostedServiceIAsyncDisposable.
- Skapa en timerbaserad tjänst.
- Registrera den anpassade implementeringen med beroendeinmatning och loggning.
Dricks
Alla exempelkällkoden "Arbetare i .NET" finns i exempelwebbläsaren för nedladdning. Mer information finns i Bläddra bland kodexempel: Arbetare i .NET.
Förutsättningar
- .NET 8.0 SDK eller senare
- En .NET-integrerad utvecklingsmiljö (IDE)
- Använd gärna Visual Studio
Skapa ett nytt projekt
Om du vill skapa ett nytt Worker Service-projekt med Visual Studio väljer du Nytt>>filprojekt....I dialogrutan Skapa ett nytt projekt söker du efter "Arbetstjänst" och väljer Mall för Arbetstjänst. Om du hellre vill använda .NET CLI öppnar du din favoritterminal i en arbetskatalog. dotnet new
Kör kommandot och ersätt <Project.Name>
med önskat projektnamn.
dotnet new worker --name <Project.Name>
Mer information om kommandot .NET CLI new worker service project finns i dotnet new worker( dotnet new worker).
Dricks
Om du använder Visual Studio Code kan du köra .NET CLI-kommandon från den integrerade terminalen. Mer information finns i Visual Studio Code: Integrerad terminal.
Skapa tidsinställd tjänst
Den tidsbaserade bakgrundstjänsten använder System.Threading.Timer klassen. Timern utlöser DoWork
metoden. Timern inaktiveras och IHostLifetime.StopAsync(CancellationToken) tas bort när tjänstcontainern tas bort på IAsyncDisposable.DisposeAsync():
Ersätt innehållet i Worker
mallen med följande C#-kod och byt namn på filen till 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;
}
}
Viktigt!
Worker
var en underklass av BackgroundService. TimerService
Nu implementerar både - och-gränssnitten IAsyncDisposableIHostedService.
TimerService
är sealed
och kaskader anropet från instansen DisposeAsync
_timer
. Mer information om "kaskadhanteringsmönstret" finns i Implementera en DisposeAsync
metod.
När StartAsync anropas instansieras timern, vilket startar timern.
Dricks
Väntar Timer inte på att tidigare körningar av DoWork
ska slutföras, så den metod som visas kanske inte är lämplig för varje scenario. Interlocked.Increment används för att öka körningsräknaren som en atomisk åtgärd, vilket säkerställer att flera trådar inte uppdateras _executionCount
samtidigt.
Ersätt det befintliga Program
innehållet med följande C#-kod:
using App.TimerHostedService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<TimerService>();
IHost host = builder.Build();
host.Run();
Tjänsten är registrerad i (Program.cs) med AddHostedService
tilläggsmetoden. Det här är samma tilläggsmetod som du använder när du registrerar BackgroundService underklasser, eftersom båda implementerar IHostedService gränssnittet.
Mer information om hur du registrerar tjänster finns i Beroendeinmatning i .NET.
Verifiera tjänstfunktioner
Om du vill köra programmet från Visual Studio väljer du F5 eller väljer menyalternativet Felsök>startfelsökning. Om du använder .NET CLI kör dotnet run
du kommandot från arbetskatalogen:
dotnet run
Mer information om körningskommandot för .NET CLI finns i dotnet run.
Låt programmet köras en stund för att generera flera steg för körningsantal. Du ser utdata som liknar följande:
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.
Om du kör programmet inifrån Visual Studio väljer du Felsöka>Sluta felsöka.... Du kan också välja Ctrl + C i konsolfönstret för att signalera annullering.
Se även
Det finns flera relaterade självstudier att tänka på: