Partager via


Utiliser des services délimités dans un BackgroundService

Lorsque vous enregistrez des implémentations de IHostedService en utilisant l'une des méthodes d'extension AddHostedService, le service est enregistré en tant que singleton. Il peut y avoir des scénarios dans lesquels vous souhaitez vous appuyer sur un service étendu. Pour plus d’informations, consultez Injection de dépendance dans .NET : Cycle de vie des services.

Dans ce tutoriel, vous allez apprendre à :

Conseil / Astuce

Tous les exemples de code source « Workers in .NET » sont disponibles dans l’Explorateur d’exemples pour le téléchargement. Pour plus d’informations, consultez les exemples de code pour Workers dans .NET.

Conditions préalables

Créer un projet

Pour créer un projet de service Worker avec Visual Studio, vous devez sélectionner Fichier>nouveau>projet.... Dans la boîte de dialogue Créer un projet, recherchez « Service Worker », puis sélectionnez modèle De service Worker. Si vous préférez utiliser l’interface CLI .NET, ouvrez votre terminal favori dans un répertoire de travail. Exécutez la commande dotnet new, et remplacez <Project.Name> par le nom de projet souhaité.

dotnet new worker --name <Project.Name>

Pour plus d’informations sur la commande de projet de service new worker de l’interface CLI .NET, consultez dotnet new worker.

Conseil / Astuce

Si vous utilisez Visual Studio Code, vous pouvez exécuter des commandes CLI .NET à partir du terminal intégré. Pour plus d’informations, consultez Visual Studio Code : Terminal intégré.

Créer des services délimités

Pour utiliser des services délimités dans un BackgroundService, créez une étendue avec l’API IServiceScopeFactory.CreateScope() . Par défaut, aucune étendue n’est créée pour un service hébergé. Le service d'arrière-plan à portée limitée contient la logique de la tâche d'arrière-plan.

namespace App.ScopedService;

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

L’interface précédente définit une méthode unique DoWorkAsync . Créez une implémentation dans une nouvelle classe nommée 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;
    }
}
  • Un ILogger est injecté dans le service à l'aide d'un constructeur primaire.
  • La DoWorkAsync méthode retourne une Task valeur et accepte le CancellationToken.
    • La méthode journalise l’identificateur d’instance—l’_instanceId est attribué chaque fois que la classe est instanciée.

Réécrire la classe Worker

Remplacez la classe existante Worker par le code C# suivant, puis renommez le fichier en ScopedBackgroundService.cs :

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);
    }
}

Dans le code précédent, alors que le stoppingToken n'est pas annulé, le IServiceScopeFactory est utilisé pour créer une portée. À partir du IServiceScope, le IScopedProcessingService est résolu. La méthode DoWorkAsync est en attente, et le stoppingToken est passé à la méthode. Enfin, l’exécution est retardée pendant 10 secondes et la boucle continue. Chaque fois que la méthode DoWorkAsync est appelée, une nouvelle instance de DefaultScopedProcessingService est créée et l’identifiant de l’instance est journalisé.

Remplacez le modèle Program.cs contenu du fichier par le code C# suivant :

using App.ScopedService;

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

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

Les services sont enregistrés dans (Program.cs). Le service hébergé est inscrit avec la méthode d’extension AddHostedService .

Pour plus d’informations sur l’enregistrement des services, consultez Injection de Dépendances dans .NET.

Vérifier la fonctionnalité de service

Pour exécuter l’application à partir de Visual Studio, sélectionnez F5 ou sélectionnez l’option de menu Démarrer> ledébogage. Si vous utilisez l’interface CLI .NET, exécutez la dotnet run commande à partir du répertoire de travail :

dotnet run

Pour plus d’informations sur la commande d’exécution de l’interface CLI .NET, consultez dotnet run.

Laissez l’application s’exécuter pour un peu pour générer plusieurs appels à DoWorkAsync, enregistrant ainsi de nouveaux identificateurs d’instance. Vous voyez une sortie similaire aux logs suivants :

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.

Si vous exécutez l’application à partir de Visual Studio, sélectionnez Déboguer>arrêter le débogage.... Vous pouvez également sélectionner Ctrl + C dans la fenêtre de console pour signaler l’annulation.

Voir aussi