In this lesson, you will learn how to orchestrate a clean application exit by intercepting termination signals to ensure in-flight requests finish before the runtime shuts down.
The Problem: Sudden Termination
When an orchestrator like Kubernetes terminates a container, it sends a SIGTERM signal. If your .NET process doesn't handle this signal, the runtime immediately begins tearing down the process, causing active HTTP requests to drop, database transactions to roll back unexpectedly, and background tasks to abort in an inconsistent state.
The Mechanism: IHostApplicationLifetime
In modern .NET applications, you shouldn't rely on manually catching global signals via Console.CancelKeyPress. Instead, utilize the IHostApplicationLifetime interface. This service acts as a bridge between the container's lifecycle events and your application's logic.
When the container receives SIGTERM, the host triggers the ApplicationStopping token. Your task is to ensure your services respect this token.
Implementing a Graceful Delay
You can inject IHostApplicationLifetime into your long-running services or middleware to perform cleanup. Here is a common pattern for a background worker:
public class GracefulWorker : BackgroundService
{
private readonly IHostApplicationLifetime _lifetime;
public GracefulWorker(IHostApplicationLifetime lifetime) => _lifetime = lifetime;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Register a callback for when the shutdown begins
using var register = _lifetime.ApplicationStopping.Register(() =>
Console.WriteLine("Shutdown signal received. Finishing tasks..."));
while (!stoppingToken.IsCancellationRequested)
{
await DoWorkAsync();
}
}
}
By respecting the stoppingToken within your loops, you prevent the runtime from forcibly killing threads while they are halfway through a critical operation. Furthermore, ASP.NET Core automatically pauses new requests when a shutdown is initiated, allowing existing requests a grace period (configured via HostOptions.ShutdownTimeout) to complete. If your process takes longer than the orchestrator’s timeout period, the container will be forcibly killed (SIGKILL), so ensure your cleanup logic is efficient and bounded.
Key Takeaway: Leverage the IHostApplicationLifetime CancellationToken to allow your services to complete pending work during the SIGTERM window, preventing data corruption and request loss.