Dela via


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

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 sealedoch 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å: