Currently using a single IHostedService with .NET Generic host, which is ran as a Windows Service.
When an unhandled exception is thrown from a worker thread (e.g. from a System.Threading.Timer callback), the application is terminated with a non-zero exit code, resulting in the SCM restarting the service (due to configured service's recovery options).
It's possible to hook into the AppDomain.CurrentDomain.UnhandledException event, which could be used to save state / perform additional logging before the application terminates. The question is, should this event callback be invoking IHostApplicationLifetime.StopApplication? The advantage is that any unmanaged resources in the service container could be disposed of, rather than just exiting.
Looking at the docs, when an unhandled exception occurs there doesn't seem to be anyway to prevent the application from crashing after it invokes the event callback. Perhaps if IHostApplicationLifetime.StopApplication was called, we could end up in a worse state, with some services being disposed before the application crashes (as host could take a while to shutdown cleanly)?
When I tested invoking StopApplication in the event callback, I noticed the application would no longer be restarted by SCM (even when setting Environment.ExitCode to 1). However, it would log "Hosting stopped", implying the host cleanup was being completed.
Here's some sample code to demonstrate what I'm talking about:
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var e = args.ExceptionObject as Exception;
try
{
_logger.Error(e, "Unhandled exception, attempting to shutdown cleanly....");
}
catch { }
Environment.ExitCode = 1; // TBD: this doesn't work, SCM doesn't restart service
// the application will try to terminate anyway, but try to cleanly shutdown
_lifetime.StopApplication(); // removing this line results in SCM restarting service.
};
new Timer((obj) => throw new Exception("Unhandled exception test"), null, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
Currently using a single IHostedService with .NET Generic host, which is ran as a Windows Service.
When an unhandled exception is thrown from a worker thread (e.g. from a System.Threading.Timer callback), the application is terminated with a non-zero exit code, resulting in the SCM restarting the service (due to configured service's recovery options).
It's possible to hook into the AppDomain.CurrentDomain.UnhandledException event, which could be used to save state / perform additional logging before the application terminates. The question is, should this event callback be invoking IHostApplicationLifetime.StopApplication? The advantage is that any unmanaged resources in the service container could be disposed of, rather than just exiting.
Looking at the docs, when an unhandled exception occurs there doesn't seem to be anyway to prevent the application from crashing after it invokes the event callback. Perhaps if IHostApplicationLifetime.StopApplication was called, we could end up in a worse state, with some services being disposed before the application crashes (as host could take a while to shutdown cleanly)?
When I tested invoking StopApplication in the event callback, I noticed the application would no longer be restarted by SCM (even when setting Environment.ExitCode to 1). However, it would log "Hosting stopped", implying the host cleanup was being completed.
Here's some sample code to demonstrate what I'm talking about:
Most relevant doc I could find on subject https://learn.microsoft.com/en-us/dotnet/core/extensions/generic-host?tabs=appbuilder#host-shutdown and https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-appdomain-unhandledexception
Using .NET Version 8.0.