Freigeben über


Verwenden Sie bereichsbezogene Dienste in einem BackgroundService

Wenn Sie Implementierungen von IHostedService mit einer der AddHostedService Erweiterungsmethoden registrieren, wird der Dienst als Singleton registriert. Es kann Szenarien geben, in denen Sie sich auf einen bereichsbezogenen Dienst verlassen möchten. Weitere Informationen finden Sie unter Dependency Injection in .NET: Lebensdauer von Diensten.

In diesem Tutorial lernen Sie Folgendes:

Tipp

Der Quellcode "Workers in .NET" ist im Beispielbrowser zum Herunterladen verfügbar. Weitere Informationen finden Sie unter Durchsuchen von Codebeispielen: Worker in .NET.

Voraussetzungen

Erstellen eines neuen Projekts

Um ein neues Worker Service-Projekt mit Visual Studio zu erstellen, wählen Sie „Datei“>„Neu“>„Projekt…“ aus. Im Dialogfeld „Neues Projekt erstellen“ suchen Sie nach „Worker Service“ und wählen die „Worker Service“-Vorlage aus. Wenn Sie lieber die .NET CLI verwenden möchten, öffnen Sie Ihr bevorzugtes Terminal in einem Arbeitsverzeichnis. Führen Sie den Befehl dotnet new aus, und ersetzen Sie <Project.Name> durch den gewünschten Projektnamen.

dotnet new worker --name <Project.Name>

Weitere Informationen zum .NET-CLI-Befehl für ein neues Workerdienstprojekt finden Sie unter dotnet new worker.

Tipp

Wenn Sie Visual Studio Code verwenden, können Sie .NET CLI-Befehle über das integrierte Terminal ausführen. Weitere Informationen finden Sie unter Visual Studio Code: Integrated Terminal.

Erstellen von bereichsbezogenen Diensten

Um bereichsbezogene Dienste in einem BackgroundServiceBereich zu verwenden, erstellen Sie einen Bereich mit der IServiceScopeFactory.CreateScope() API. Bereiche werden für einen gehosteten Dienst nicht standardmäßig erstellt. Der abgegrenzte Hintergrunddienst enthält die Logik der Hintergrundaufgabe.

namespace App.ScopedService;

public interface IScopedProcessingService
{
    Task DoWorkAsync(CancellationToken stoppingToken);
}

Die vorangehende Schnittstelle definiert eine einzelne DoWorkAsync Methode. Erstellen Sie eine Implementierung in einer neuen Klasse namens DefaultScopedProcessingService.cs:

namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private readonly string _instanceId = Guid.NewGuid().ToString();

    public Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{ServiceName} doing work, instance ID: {Id}",
            nameof(DefaultScopedProcessingService),
            _instanceId);

        return Task.CompletedTask;
    }
}
  • Es ILogger wird mithilfe eines primären Konstruktors in den Dienst eingefügt.
  • Die DoWorkAsync Methode gibt eine Task und akzeptiert die CancellationToken.
    • Die Methode protokolliert den Instanzbezeichner– die _instanceId wird immer dann zugewiesen, wenn die Klasse instanziiert wird.

Schreibe die Worker-Klasse um

Ersetzen Sie die vorhandene Worker Klasse durch den folgenden C#-Code, und benennen Sie die Datei in ScopedBackgroundService.cs um:

namespace App.ScopedService;

public sealed class ScopedBackgroundService(
    IServiceScopeFactory serviceScopeFactory,
    ILogger<ScopedBackgroundService> logger) : BackgroundService
{
    private const string ClassName = nameof(ScopedBackgroundService);

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is running.", ClassName);

        while (!stoppingToken.IsCancellationRequested)
        {
            using IServiceScope scope = serviceScopeFactory.CreateScope();

            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);

            await Task.Delay(10_000, stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is stopping.", ClassName);

        await base.StopAsync(stoppingToken);
    }
}

Im vorherigen Code, während der stoppingToken Vorgang nicht abgebrochen wird, wird IServiceScopeFactory verwendet, um einen Bereich zu erstellen. Aus dem IServiceScope wird IScopedProcessingService aufgelöst. Die DoWorkAsync Methode wird erwartet, und die stoppingToken Methode wird an die Methode übergeben. Schließlich wird die Ausführung 10 Sekunden lang verzögert, und die Schleife wird fortgesetzt. Jedes Mal, wenn die DoWorkAsync Methode aufgerufen wird, wird eine neue Instanz der DefaultScopedProcessingService Erstellt und der Instanzbezeichner protokolliert.

Ersetzen Sie die Vorlage Program.cs Dateiinhalte durch den folgenden C#-Code:

using App.ScopedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();

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

Die Dienste werden in (Program.cs) registriert. Der gehostete Dienst wird bei der AddHostedService Erweiterungsmethode registriert.

Weitere Informationen zum Registrieren von Diensten finden Sie unter Dependency Injection in .NET.

Überprüfen der Dienstfunktionalität

Um die Anwendung in Visual Studio auszuführen, wählen Sie F5 aus, oder wählen Sie die Menüoption " Debuggen>starten" aus. Wenn Sie die .NET CLI verwenden, führen Sie den dotnet run Befehl aus dem Arbeitsverzeichnis aus:

dotnet run

Weitere Informationen zum .NET CLI-Ausführungsbefehl finden Sie unter dotnet run.

Lassen Sie die Anwendung eine Weile laufen, um mehrere Aufrufe zu DoWorkAsync zu generieren, wodurch neue Instanzkennungen protokolliert werden. Es wird eine Ausgabe angezeigt, die den folgenden Protokollen ähnelt:

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
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: .\scoped-service
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

Wenn Sie die Anwendung in Visual Studio ausführen, wählen Sie "Debuggen>beenden" aus. Alternativ können Sie imKonsolenfenster STRG + C auswählen, um den Abbruch zu signalisieren.

Siehe auch