IHostedService De interface implementeren

Wanneer u eindige controle nodig hebt buiten de opgegeven BackgroundService, kunt u uw eigen IHostedServiceimplementeren. De IHostedService interface is de basis voor alle langlopende services in .NET. Aangepaste implementaties worden geregistreerd bij de AddHostedService<THostedService>(IServiceCollection) extensiemethode.

In deze zelfstudie leert u het volgende:

  • Implementeer de IHostedServiceen IAsyncDisposable interfaces.
  • Een timerservice maken.
  • Registreer de aangepaste implementatie met afhankelijkheidsinjectie en logboekregistratie.

Tip

Alle voorbeeldbroncode 'Workers in .NET' is beschikbaar in de voorbeeldenbrowser om te downloaden. Zie Codevoorbeelden bekijken: Workers in .NET voor meer informatie.

Vereisten

  • De .NET 8.0 SDK of hoger
  • Een .NET Integrated Development Environment (IDE)
    • U kunt Visual Studio gerust gebruiken

Een nieuw project maken

Als u een nieuw Worker Service-project wilt maken met Visual Studio, selecteert u Bestand>nieuw>project.... Zoek in het dialoogvenster Een nieuw project maken naar 'Worker Service' en selecteer de sjabloon Worker Service. Als u liever de .NET CLI gebruikt, opent u uw favoriete terminal in een werkmap. Voer de dotnet new opdracht uit en vervang de door de <Project.Name> gewenste projectnaam.

dotnet new worker --name <Project.Name>

Zie dotnet new worker voor meer informatie over de opdracht .NET CLI new worker service project.

Tip

Als u Visual Studio Code gebruikt, kunt u .NET CLI-opdrachten uitvoeren vanuit de geïntegreerde terminal. Zie Visual Studio Code: Integrated Terminal voor meer informatie.

Timerservice maken

De op timer gebaseerde achtergrondservice maakt gebruik van de System.Threading.Timer klasse. De timer activeert de DoWork methode. De timer is uitgeschakeld IHostLifetime.StopAsync(CancellationToken) en verwijderd wanneer de servicecontainer wordt verwijderd op IAsyncDisposable.DisposeAsync():

Vervang de inhoud van de Worker sjabloon door de volgende C#-code en wijzig de naam van het bestand in 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;
    }
}

Belangrijk

Het Worker was een subklasse van BackgroundService. TimerService Nu worden zowel de IHostedService, als IAsyncDisposable de interfaces geïmplementeerd.

Het TimerService is sealed, en trapsgewijs de aanroep van het DisposeAsync_timer exemplaar. Zie Een methode implementeren DisposeAsync voor meer informatie over het 'trapsgewijze verwijderingspatroon'.

Wanneer StartAsync wordt aangeroepen, wordt de timer geïnstantieerd, waardoor de timer wordt gestart.

Tip

Er Timer wordt niet gewacht tot eerdere uitvoeringen zijn DoWork voltooid, dus de weergegeven benadering is mogelijk niet geschikt voor elk scenario. Interlocked.Increment wordt gebruikt om het uitvoeringsteller als een atomische bewerking te verhogen, waardoor meerdere threads niet gelijktijdig worden bijgewerkt _executionCount .

Vervang de bestaande Program inhoud door de volgende C#-code:

using App.TimerHostedService;

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

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

De service is geregistreerd in (Program.cs) met de AddHostedService extensiemethode. Dit is dezelfde extensiemethode die u gebruikt bij het registreren van BackgroundService subklassen, omdat ze beide de IHostedService interface implementeren.

Zie Afhankelijkheidsinjectie in .NET voor meer informatie over het registreren van services.

Servicefunctionaliteit controleren

Als u de toepassing vanuit Visual Studio wilt uitvoeren, selecteert u F5 of selecteert u de menuoptie Foutopsporing> starten. Als u de .NET CLI gebruikt, voert u de dotnet run opdracht uit vanuit de werkmap:

dotnet run

Zie dotnet run voor meer informatie over de .NET CLI-run-opdracht.

Laat de toepassing een beetje uitvoeren om verschillende stappen voor het aantal uitvoeringen te genereren. De uitvoer ziet er ongeveer als volgt uit:

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.

Als u de toepassing vanuit Visual Studio uitvoert, selecteert u Foutopsporing>stoppen.... U kunt ook Ctrl + C selecteren in het consolevenster om annulering te signaleren.

Zie ook

Er zijn verschillende gerelateerde zelfstudies die u moet overwegen: