-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
Description
When a Microsoft.Extensions.Hosting.BackgroundService running in the default Microsoft.Extensions.Hosting.IHost throws an exception from its ExecuteAsync method and HostOptions.BackgroundServiceExceptionBehavior is set to BackgroundServiceExceptionBehavior.StopHost (the default), the host is stopped. As a result, awaiting RunAsync or StopAsync on the host completes and the application typically exits.
Previously, awaiting RunAsync or StopAsync on the host completed successfully and this usually meant the application exited with a success exit code (zero).
Now, awaiting RunAsync or StopAsync on the host will throw an exception, which will usually mean that the application will exit with a failure exit code (non-zero).
Version
.NET 11 Preview 3
Previous behavior
When a BackgroundService throws an exception from its ExecuteAsync method and HostOptions.BackgroundServiceExceptionBehavior is set to BackgroundServiceExceptionBehavior.StopHost, the task returned from calling RunAsync , StopAsync or WaitForShutdownAsync on the default host completes successfully.
New behavior
When a BackgroundService throws an exception from its ExecuteAsync method and HostOptions.BackgroundServiceExceptionBehavior is set to BackgroundServiceExceptionBehavior.StopHost, the task returned from calling RunAsync, StopAsync or WaitForShutdownAsync on the default host fails with an exception. If a single service fails, the exception thrown by the service is rethrown. If multiple services fail, their exceptions are combined into an AggregateException.
Type of breaking change
- Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
- Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
- Behavioral change: Existing binaries might behave differently at run time.
Reason for change
If an application stops because of a failure, the application shouldn't exit with a success exit code. The previous behavior was effectively hiding the failure, making it harder to detect and diagnose the issue that caused the exception.
Recommended action
The recommended action is to do nothing: a failing application should exit with a failure exit code, which is the new behavior.
If it is necessary to maintain the previous behavior (success exit code), wrap the await of RunAsync or StopAsync on the host in a try-catch block.
Feature area
Extensions
Affected APIs
IHost.StopAsync with the default implementation of IHost and any methods that call it:
HostingAbstractionsHostExtensions.RunAsyncHostingAbstractionsHostExtensions.RunHostingAbstractionsHostExtensions.StopAsyncHostingAbstractionsHostExtensions.WaitForShutdownAsyncHostingAbstractionsHostExtensions.WaitForShutdown
Further information
The relevant PR is dotnet/runtime#124863 and the issue is dotnet/runtime#67146.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status