Utiliser des services délimités dans un BackgroundService
Lorsque vous inscrivez des implémentations de l’utilisation IHostedService de l’une AddHostedService des méthodes d’extension, le service est inscrit en tant que singleton. Il peut y avoir des scénarios dans lesquels vous souhaitez vous appuyer sur un service délimité. Pour plus d’informations, consultez Injection de dépendances dans .NET : Durées de vie du service.
Dans ce tutoriel, vous allez apprendre à :
- Résoudre les dépendances délimitées dans un singleton BackgroundService.
- Déléguer le travail à un service délimité.
- Implémenter un
override
. de BackgroundService.StopAsync(CancellationToken).
Conseil
Tout le code source d’exemple « Workers dans .NET » peut être téléchargé dans l’Explorateur d’exemples. Pour plus d’informations, consultez Parcourir les exemples de code : Workers dans .NET.
Prérequis
- Kit de développement logiciel (SDK) .NET 8.0 ou versions antérieures
- Un IDE (environnement de développement intégré) .NET
- N’hésitez pas à utiliser Visual Studio
Création d'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 « Worker Service », puis sélectionnez Modèle Worker Service. 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 le <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
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 au sein d’un BackgroundService
, créez une étendue. Par défaut, aucune étendue n’est créée pour un service hébergé. Le service en arrière-plan délimité contient la logique de la tâche en 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
. Pour définir l’implémentation par défaut :
- Le service est asynchrone. La méthode
DoWorkAsync
retourne unTask
. À des fins de démonstration, un délai de dix secondes est attendu dans laDoWorkAsync
méthode. - Une ILogger est injectée dans le service.:
namespace App.ScopedService;
public sealed class DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
private int _executionCount;
public async Task DoWorkAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
++ _executionCount;
logger.LogInformation(
"{ServiceName} working, execution count: {Count}",
nameof(DefaultScopedProcessingService),
_executionCount);
await Task.Delay(10_000, stoppingToken);
}
}
}
Le service hébergé crée une étendue pour résoudre le service des tâches en arrière-plan délimitées pour appeler sa DoWorkAsync
méthode. DoWorkAsync
retourne un Task
, qui est attendu dans ExecuteAsync
:
Réécrire la classe Worker
Remplacez la classe Worker
existante par le code C# suivant et renommez le fichier 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);
await DoWorkAsync(stoppingToken);
}
private async Task DoWorkAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is working.", ClassName);
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
IScopedProcessingService scopedProcessingService =
scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
logger.LogInformation(
"{Name} is stopping.", ClassName);
await base.StopAsync(stoppingToken);
}
}
Dans le code précédent, une étendue explicite est créée et l’implémentation de IScopedProcessingService
est résolue depuis la fabrique d’étendue du service d’injection de dépendances. L’instance de service résolue est délimitée et sa DoWorkAsync
méthode est attendue.
Remplacez le contenu du fichier modèle Program.cs 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 inscrits dans (Program.cs). Le service hébergé est inscrit avec la méthode d’extension AddHostedService
.
Pour plus d’informations sur l’inscription de services, consultez Injection de dépendances dans .NET.
Vérifier les fonctionnalités du service
Pour exécuter l’application à partir de Visual Studio, sélectionnez F5 ou sélectionnez l’option de menu Déboguer>Démarrer le débogage. Si vous utilisez l’interface CLI .NET, exécutez la commande dotnet run
à 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 un peu pour générer plusieurs incréments de nombre d’exécutions. Vous devez voir des informations semblables à ce qui suit :
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is running.
info: App.ScopedService.ScopedBackgroundService[0]
ScopedBackgroundService is working.
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService working, execution count: 1
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 working, execution count: 2
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService working, execution count: 3
info: App.ScopedService.DefaultScopedProcessingService[0]
DefaultScopedProcessingService working, execution count: 4
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.