Comment appeler une méthode d’un service singleton à exécuter tout au long de la durée de vie de l’application

J’ai implémenté un bus d’événements Kafka en tant que service singleton dans Net Core. Le service lui-même est configuré avec Autofac dans Startup.cs. Le service a une méthode Listen() :

 public void Listen() { using(var consumer = new Consumer(_config, null, new SsortingngDeserializer(Encoding.UTF8))) { consumer.Subscribe(new ssortingng[] { "business-write-topic" }); consumer.OnMessage += (_, msg) => { Console.WriteLine($"Topic: {msg.Topic} Partition: {msg.Partition} Offset: {msg.Offset} {msg.Value}"); consumer.CommitAsync(msg); }; while (true) { consumer.Poll(100); } } } 

D’après ce que je comprends, pour que cette méthode écoute constamment les messages pendant la durée de vie de l’application, je dois l’appeler dans Program.cs à partir de l’hôte Web en obtenant en quelque sorte le fournisseur de services associé à l’hôte, puis en récupérant une instance du fichier. service, et en appelant la méthode.

J’ai configuré mon Program.cs à partir du modèle Net Core 2.1 par défaut comme suit:

 public class Program { public static void Main(ssortingng[] args) { var host = CreateWebHost(args); host.Run(); } public static IWebHost CreateWebHost(ssortingng[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() .Build(); } 

Au-delà de la disponibilité de l’hôte afin que je puisse accéder aux services, je ne sais pas où aller à partir de maintenant. J’ai cherché des questions similaires et lu dans la documentation officielle, mais je n’arrive pas à comprendre comment accéder au service pour pouvoir appeler la méthode Listen() .

Est-ce le moyen “idéal” pour atteindre mon objective? Si oui, comment puis-je procéder? Et si ce n’est pas le cas, c’est-à-dire si ce genre de tâche est généralement accompli d’une autre manière, comment puis-je m’y prendre?

Je suggère d’utiliser IHostedService . Les implémentations IHostedService sont enregistrées en tant que singletons et s’exécutent tout le temps jusqu’à la fermeture du serveur.

Créer cette classe de base

 public abstract class HostedService : IHostedService { private Task executingTask; private CancellationTokenSource cancellationTokenSource; public Task StartAsync(CancellationToken cancellationToken) { this.cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); this.executingTask = this.ExecuteAsync(this.cancellationTokenSource.Token); return this.executingTask.IsCompleted ? this.executingTask : Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { if (this.executingTask == null) { return; } this.cancellationTokenSource.Cancel(); await Task.WhenAny(this.executingTask, Task.Delay(-1, cancellationToken)); } protected abstract Task ExecuteAsync(CancellationToken cancellationToken); } 

Puis créez l’hôte consommateur

 public class ConsumerHost : HostedService { protected override async Task ExecuteAsync(CancellationToken cancellationToken) { using (var consumer = new Consumer(_config, null, new SsortingngDeserializer(Encoding.UTF8))) { consumer.Subscribe(new ssortingng[] {"business-write-topic"}); consumer.OnMessage += (_, msg) => { Console.WriteLine( $"Topic: {msg.Topic} Partition: {msg.Partition} Offset: {msg.Offset} {msg.Value}"); consumer.CommitAsync(msg); }; while (!cancellationToken.IsCancellationRequested) // will make sure to stop if the application is being shut down! { consumer.Poll(100); await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken); } } } } 

Maintenant, dans votre classe de démarrage dans la méthode ConfigureService, ajoutez le singleton

 public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } 

Ce service sera désormais activé lorsque l’hôte Web aura terminé la construction et sera arrêté lorsque vous arrêterez le serveur. Inutile de le déclencher manuellement, laissez l’hôte Web le faire pour vous.

Je pense que BackgroundService est ce dont vous avez besoin.

 public class ListnerBackgroundService : BackgroundService { private readonly ListnerService service; public ListnerBackgroundService(ListnerService service) { this.service = service; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { service.Listen(); return Task.CompletedTask; } } 

Et enregistrez-le:

 public void ConfigureServices(IServiceCollection services) { ... services.AddSingleton(); ... }