web-dev-qa-db-fra.com

Démarrage / arrêt / pause manuel d'ASP.NET Core IHostedService (?)

Je souhaite implémenter une instance IHostedService récurrente (temporisée) dans ASPNET Core pouvant être arrêtée et démarrée à la demande. D'après ce que je comprends, les services IHostedService sont démarrés par la structure au démarrage de l'application.

Toutefois, j'aimerais pouvoir démarrer/arrêter le service "manuellement", éventuellement en utilisant une bascule marche/arrêt via une interface utilisateur. Dans l'idéal, l'état "désactivé" disposerait du service en cours d'exécution et l'état "activé" créerait une nouvelle instance.

J'ai lu la documentation MS ici: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/Host/hosted-services?view=aspnetcore-2.1 .

Mon idée initiale était d'obtenir une instance du service en cours d'exécution puis d'appeler la méthode publique StopAsync(CancellationToken token). Cependant, je suis un peu coincé quand il s'agit de quel jeton je devrais passer, et on pourrait en dire autant de la méthode StartAsync(CancellationToken cancellationToken).

Des idées sur la façon dont cela devrait être fait, ou si c'est même conseillé? Mon approche va-t-elle en quelque sorte à l'encontre de la conception des services hébergés dans ASPNET Core?

EDIT 7.27.2018

Il apparaît donc, après quelques recherches supplémentaires (c'est-à-dire reading la documentation: D) que les méthodes de services hébergés StartAsync/StopAsync sont effectivement censées coïncider avec la durée de vie de l'application. Les IHostedServices enregistrés ne semblent pas être ajoutés au conteneur DI pour être injectés dans d'autres classes.

Par conséquent, je ne pense pas que mon idée initiale fonctionnera. Pour l'instant, j'ai enregistré mes services avec des dépendances de configuration (IOptions<T>) pouvant être mis à jour au moment de l'exécution. Pendant le traitement des services hébergés, il vérifiera la configuration pour voir si elle doit continuer, sinon il attendra simplement (au lieu d'arrêter ou de supprimer le service hébergé).

Je marquerai probablement ceci comme ma réponse bientôt, à moins d’entendre d’autres idées.

15
K. Akins

Pour StopAsync(CancellationToken token), vous pouvez transmettre new System.Threading.CancellationToken(). Dans la définition de public CancellationToken(bool canceled), canceled indique l'état du jeton. Pour votre scénario, il n'est pas nécessaire de spécifier le canceled puisque vous souhaitez arrêter le service.

Vous pouvez suivre ci-dessous étape par étape:

  1. Créer IHostedService

       public class RecureHostedService : IHostedService, IDisposable
     {
    private readonly ILogger _log;
    private Timer _timer;
    public RecureHostedService(ILogger<RecureHostedService> log)
    {
        _log = log;
    }
    
    public void Dispose()
    {
        _timer.Dispose();
    }
    
    public Task StartAsync(CancellationToken cancellationToken)
    {
        _log.LogInformation("RecureHostedService is Starting");
        _timer = new Timer(DoWork,null,TimeSpan.Zero, TimeSpan.FromSeconds(5));
        return Task.CompletedTask;
    }
    
    public Task StopAsync(CancellationToken cancellationToken)
    {
        _log.LogInformation("RecureHostedService is Stopping");
        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }
    private void DoWork(object state)
    {
        _log.LogInformation("Timed Background Service is working.");
    }
    }
    
  2. Inscrivez-vous IHostedService

        services.AddSingleton<IHostedService, RecureHostedService>();
    
  3. Service de démarrage et d'arrêt

     public class HomeController : Controller {
     private readonly RecureHostedService _recureHostedService;
     public HomeController(IHostedService hostedService)
     {
         _recureHostedService = hostedService as RecureHostedService;
     }
     public IActionResult About()
     {
         ViewData["Message"] = "Your application description page.";
         _recureHostedService.StopAsync(new System.Threading.CancellationToken());
         return View();
     }
    
     public IActionResult Contact()
     {
         ViewData["Message"] = "Your contact page.";
         _recureHostedService.StartAsync(new System.Threading.CancellationToken());
         return View();
     } }
    
10
Tao Zhou