The IApplicationLifetime interface allows hosted services to gracefully handle startup and shutdown events. It has three properties of type CancellationToken.
- ApplicationStarted
- ApplicationStopping
- ApplicationStopped
You can register callbacks for one or more of those notifications.
public HostedService( ILogger<HostedService> logger, IApplicationLifetime applicationLifetime) { _logger = logger; _applicationLifetime = applicationLifetime; } public Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Entering StartAsync"); _applicationLifetime.ApplicationStarted.Register(OnStarted); _applicationLifetime.ApplicationStopping.Register(OnStopping); _applicationLifetime.ApplicationStopped.Register(OnStopped); _timer = new Timer( ScheduledTask, this, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Entering StopAsync"); return Task.CompletedTask; } private void OnStarted() { _logger.LogInformation("OnStarted called."); } private void OnStopping() { _logger.LogInformation("OnStopping called."); } private void OnStopped() { _logger.LogInformation("OnStopped called."); }
The IApplicationLifetime interface also has a StopApplication method which unsurprisingly does just that, which is to terminate the current application.
private void ScheduledTask(object state) { var source = state as HostedService; _logger.LogInformation($"ScheduledTask invocation {source._count} via timer."); if (source._count++ == 3) { _logger.LogInformation("Shutting down..."); source._applicationLifetime.StopApplication(); }; }
The screenshot below shows the order in which these notifications are fired. It’s quite intuitive and just as you’d expect.