-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BackgroundService will not observe exceptions thrown in ExecuteAsync #68165
Comments
Tagging subscribers to this area: @dotnet/area-extensions-hosting Issue DetailsIf an exception is thrown in the ExecuteAsync method of a class derived from BackgroundService, the exception is never observed on after StopApplication() is called. This causes the program to exit with Exit Code 0. This causes problems with orchestrators that will not restart a service if it ends with exit code 0. This is due to this line of code: runtime/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs Line 76 in a21b9a2
Task.WhenAny returns a Task. The parent task will always be RanToCompletion with Exception as null. The Result needs to be awaited or checked for IsFaulted in order for the ExecuteAsync exception to be observed.
|
My quick and dirty fix for my re-implementation of BackgroundService was this: public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (this._executeTask == null)
{
return;
}
try
{
// Signal cancellation to the executing method
this._stoppingCts.Cancel();
}
finally
{
// Wait until the task completes or the stop token triggers
var final = await Task.WhenAny(this._executeTask, Task.Delay(Timeout.Infinite, cancellationToken)).ConfigureAwait(false);
// WhenAny returns a Task<Task>. Its own Task is RanToCompletion without any exceptions, so any exceptions
// from _executeTask won't be bubbled up.
// So we can await its result Task that completed and if it had any exceptions, those will now be observed.
await final;
}
} |
@Bpoe - can you attach a minimal reproduction? |
Repro Step:
Expected Result
Actual Result
|
Confirmed repro, and that it is not a regression. Thanks for the report. |
@maryamariyan I also noticed this behavior recently. I can very gladly take a look (since I am affected myself), if is not a big priority. If that's okay with you, please assign me so I don't lose track. |
@deeprobin how are you affected by this bug? Have you considered logging when you are calling StopApplication? Also you could consider using Closing as we have no plans to fix this. |
@maryamariyan - Can you please provide an explanation of why you are not fixing this issue? An also why you closed it as Completed when nothing was done? The |
Let me try to explain it in other words (as I understood the issue of @Bpoe): In case the In case of an error, however, it is desired to return an exit code that is not 0. I am not sure if this is a bug or an enhancement. Nevertheless, this is a good point. |
I could imagine that would be a breaking change. I mean iirc the host does not terminate the application directly in case of an error but the context is passed to the calling method after termination (in your case probably Program.Main). |
If an exception is thrown in the ExecuteAsync method of a class derived from BackgroundService, the exception is never observed on after StopApplication() is called. This causes the program to exit with Exit Code 0. This causes problems with orchestrators that will not restart a service if it ends with exit code 0.
This is due to this line of code:
runtime/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs
Line 76 in a21b9a2
Task.WhenAny returns a
Task<Task>
. The parent task will always be RanToCompletion with Exception as null. The Result needs to be awaited or checked for IsFaulted in order for the ExecuteAsync exception to be observed.The text was updated successfully, but these errors were encountered: