Why unhandled exceptions inside BackgroundService.ExecuteAsync crash the entire .NET application by default:
In .NET 6+, HostOptions.BackgroundServiceExceptionBehavior defaults to StopHost, shutting down your API server if a background timer throws an unhandled exception.
Robust Background Service Pattern:
public class IngestionWorker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await ProcessWorkQueueAsync(stoppingToken);
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
// Normal graceful shutdown, exit loop
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing background batch. Retrying in 5s...");
await Task.Delay(5000, stoppingToken);
}
}
}
}