From 257d8ac5b0d86fc24acbd023c1c792c3f6f5aa99 Mon Sep 17 00:00:00 2001 From: Dion Williams <844245+dionrhys@users.noreply.github.com> Date: Sun, 26 Apr 2026 15:10:53 +0100 Subject: [PATCH 1/2] Update hosted-services.md to reflect BackgroundService.StartAsync breaking change As of https://github.com/dotnet/runtime/pull/116283 (in .NET 10), `BackgroundService.StartAsync` no longer blocks until the `BackgroundService.ExecuteAsync` implementation reaches an `await` point; `StartAsync` now always runs `ExecuteAsync` on the thread pool using `Task.Run`. --- aspnetcore/fundamentals/host/hosted-services.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/host/hosted-services.md b/aspnetcore/fundamentals/host/hosted-services.md index 77628c12822c..60ce31669f5a 100644 --- a/aspnetcore/fundamentals/host/hosted-services.md +++ b/aspnetcore/fundamentals/host/hosted-services.md @@ -80,7 +80,7 @@ The hosted service is activated once at app startup and gracefully shut down at is a base class for implementing a long running . -[ExecuteAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.ExecuteAsync%2A) is called to run the background service. The implementation returns a that represents the entire lifetime of the background service. No further services are started until [ExecuteAsync becomes asynchronous](https://github.com/dotnet/extensions/issues/2149), such as by calling `await`. Avoid performing long, blocking initialization work in `ExecuteAsync`. The host blocks in [StopAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.StopAsync%2A) waiting for `ExecuteAsync` to complete. +[ExecuteAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.ExecuteAsync%2A) is called on the thread pool to run the background service. The implementation returns a that represents the entire lifetime of the background service. The host blocks in [StopAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.StopAsync%2A) waiting for `ExecuteAsync` to complete. The cancellation token is triggered when [IHostedService.StopAsync](xref:Microsoft.Extensions.Hosting.IHostedService.StopAsync%2A) is called. Your implementation of `ExecuteAsync` should finish promptly when the cancellation token is fired in order to gracefully shut down the service. Otherwise, the service ungracefully shuts down at the shutdown timeout. For more information, see the [IHostedService interface](#ihostedservice-interface) section. From 548cf053eb343076669aff7c0b972c0099e47435 Mon Sep 17 00:00:00 2001 From: Dion Williams <844245+dionrhys@users.noreply.github.com> Date: Sun, 26 Apr 2026 15:27:07 +0100 Subject: [PATCH 2/2] Fix updated doc to only apply to >= .NET 10 --- aspnetcore/fundamentals/host/hosted-services.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/aspnetcore/fundamentals/host/hosted-services.md b/aspnetcore/fundamentals/host/hosted-services.md index 60ce31669f5a..f88952d7b8b2 100644 --- a/aspnetcore/fundamentals/host/hosted-services.md +++ b/aspnetcore/fundamentals/host/hosted-services.md @@ -80,8 +80,22 @@ The hosted service is activated once at app startup and gracefully shut down at is a base class for implementing a long running . +:::moniker-end + +:::moniker range=">= aspnetcore-10.0" + [ExecuteAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.ExecuteAsync%2A) is called on the thread pool to run the background service. The implementation returns a that represents the entire lifetime of the background service. The host blocks in [StopAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.StopAsync%2A) waiting for `ExecuteAsync` to complete. +:::moniker-end + +:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0" + +[ExecuteAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.ExecuteAsync%2A) is called to run the background service. The implementation returns a that represents the entire lifetime of the background service. No further services are started until [ExecuteAsync becomes asynchronous](https://github.com/dotnet/extensions/issues/2149), such as by calling `await`. Avoid performing long, blocking initialization work in `ExecuteAsync`. The host blocks in [StopAsync(CancellationToken)](xref:Microsoft.Extensions.Hosting.BackgroundService.StopAsync%2A) waiting for `ExecuteAsync` to complete. + +:::moniker-end + +:::moniker range=">= aspnetcore-8.0" + The cancellation token is triggered when [IHostedService.StopAsync](xref:Microsoft.Extensions.Hosting.IHostedService.StopAsync%2A) is called. Your implementation of `ExecuteAsync` should finish promptly when the cancellation token is fired in order to gracefully shut down the service. Otherwise, the service ungracefully shuts down at the shutdown timeout. For more information, see the [IHostedService interface](#ihostedservice-interface) section. For more information, see the [BackgroundService](https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/BackgroundService.cs) source code.