asp.net-core.net-coreihostedservice

What is the lifecycle of an IHostedService/BackgroundService?


After StopAsync is called on an IHostedService, can StartAsync be called again on the same instance?

If so, this would imply that ExecuteAsync could be called more than once on the same BackgroundService instance.


Solution

  • After StopAsync is called on an IHostedService, can StartAsync be called again on the same instance?

    --Yes

    a minimal Blazor server example:

    public class MyBackGroundService : IHostedService, IDisposable
     {
         private readonly ILogger<MyBackGroundService> _log;
         private Timer _timer;
    
         private int index { get; set; }
    
    
         public bool isRunning { get; set; }=false;
         public MyBackGroundService(ILogger<MyBackGroundService> log)
         {
             _log = log;
             index=new Random().Next(0,20);
         }
    
         public void Dispose()
         {
             _timer.Dispose();
         }
    
         public Task StartAsync(CancellationToken cancellationToken)
         {
             isRunning=true;
            
             _timer = new Timer(Do, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
             return Task.CompletedTask;
         }
    
         public Task StopAsync(CancellationToken cancellationToken)
         {
             isRunning = false;
             _log.LogInformation($"{DateTime.Now} BackService{index} is Stopping");
             _timer?.Change(Timeout.Infinite, 0);
             return Task.CompletedTask;
         }
         private void Do(object o)
         {
             _log.LogInformation($"Background Service{index} is working.  {DateTime.Now}");
             try
             {
                 
                 // dosometing 
             }
             catch (Exception e)
             {
                
                 _log.LogInformation("Error: {0}", e.Message);
                 throw e;
    
             }
         }
     }
    

    in program.cs:

    builder.Services.AddSingleton<MyBackGroundService>();
    builder.Services.AddHostedService<MyBackGroundService>();
    

    in razor component:

    @inject MyBackGroundService backgroundservice;
    
    <PageTitle>Counter</PageTitle>
    
    <button @onclick="start">Start</button>
    <button @onclick="stop">Stop</button>
    
    
    
    
    @code {
        protected override void OnInitialized()
        {
            if (backgroundservice.isRunning)
            {
                backgroundservice.StopAsync(new System.Threading.CancellationToken());
            }
            base.OnInitialized();
        }
        public void start()
        {
            if (!backgroundservice.isRunning)
            {
                backgroundservice.StartAsync(new System.Threading.CancellationToken());
            }
    
        }
        public void stop()
        {
            if (backgroundservice.isRunning)
            {
                backgroundservice.StopAsync(new System.Threading.CancellationToken());
            }
    
        }
    }
    

    The one registed as Singleton could start and stop for multipule times,the one registered with AddHostedService method would start when your app start,and stop when your app shut down

    I clicked buttons follow the steps: start--stop--start,the console: enter image description here