Description
In summary, if I
- Install the "Application Initialization module" in IIS
- Set "StartMode: AlwaysRunning" for the app pool
- Set "Preload Enabled: True" for the website
The IHostedService StopAsync method and OnStopping/OnStopped events are not called when either recycling the app pool or restarting IIS (iisreset). Just disabling "Preload Enabled" fixes the issue.
Not sure this is an IIS or .Net Core issue.
Here is the output of dotnet --info
Host (useful for support):
Version: 3.1.9
Commit: 774fc3d6a9
.NET Core SDKs installed:
No SDKs were found.
.NET Core runtimes installed:
Microsoft.AspNetCore.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
IIS on Windows Server 2019 1809, but same issue on Windows 10 1909.
Code sample:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureServices(services =>
{
services.AddHostedService<LifetimeEventsHostedService>();
});
}
internal class LifetimeEventsHostedService : IHostedService
{
private readonly ILogger _logger;
private readonly IHostApplicationLifetime _appLifetime;
public LifetimeEventsHostedService(
ILogger<LifetimeEventsHostedService> logger,
IHostApplicationLifetime appLifetime)
{
_logger = logger;
_appLifetime = appLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_appLifetime.ApplicationStarted.Register(OnStarted);
_appLifetime.ApplicationStopping.Register(OnStopping);
_appLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("StopAsync has been called.");
return Task.CompletedTask;
}
private void OnStarted()
{
_logger.LogInformation("OnStarted has been called.");
}
private void OnStopping()
{
_logger.LogInformation("OnStopping has been called.");
}
private void OnStopped()
{
_logger.LogInformation("OnStopped has been called.");
}
}
StartAsync and OnStarted are always called. It seems the process is killed by IIS instead of cleanly shutting down when preload is enabled.