Search code examples
c#asp.net-corebackground-service

Extending Application Shutdown Timeout


In my .NET Core 2.1 application, I have a service that inherits from the BackgroundService class which kicks off a long-running service on a new thread. This service then hits a scoped service which reads from the database and sends some emails. I am attempting to test my handling of a graceful shutdown of the application but am running into an odd issue in my testing scenario.

After reading over the MSDN blog entry for BackgroundService, it is mentioned:

"By default, the cancellation token is set with a 5 second timeout, although you can change that value when building your WebHost using the UseShutdownTimeout extension of the IWebHostBuilder. This means that our service is expected to cancel within 5 seconds otherwise it will be more abruptly killed."

The following code would be changing that time to 10 seconds.

WebHost.CreateDefaultBuilder(args)

.UseShutdownTimeout(TimeSpan.FromSeconds(10))

...

In my Program.cs file, I have implemented this Extension Method (and have also tried to use the UseSettings method as well) to try and extend my timeout shutdown as follows:

public static IWebHost BuildWebHost(string[] args) =>
      WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseSerilog()
        //.UseSetting(WebHostDefaults.ShutdownTimeoutKey, "20")
        .UseShutdownTimeout(TimeSpan.FromSeconds(20))
        .Build();

I have a breakpoint in my scoped service where I am attempting to test the addition of this timeout by setting a wait of 10 seconds and closing the console to initiate the shutdown once the thread is waiting. I am finding however that after 5 seconds of the shutdown being initiated, the application is being killed as if it's still using the default of 5 seconds for the shutdown instead of the new 20. What could be the cause of this behavior?

Log.Information("preparing to sleep thread for 10 seconds");
//Thread.Sleep(10000);
await Task.Delay(TimeSpan.FromSeconds(10));
Log.Information("thread awakened");

Solution

  • My particular ASP.NET Console Application didn't have a web.config file, so I created one of those and then added the shutdownTimeLimit property to the aspNetCore module section.

    <aspNetCore shutdownTimeLimit="20" processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false">