Skip to content

IHostedService StopAsync and OnStopping/OnStopped events not called with IIS preload enabled #28089

Open
@lpn-ch

Description

@lpn-ch

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: Attention 👋This issue needs the attention of a contributor, typically because the OP has provided an update.affected-very-fewThis issue impacts very few customersarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsbugThis issue describes a behavior which is not expected - a bug.investigateseverity-minorThis label is used by an internal tool

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions