9.0 KiB
title | author | description | monikerRange | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|---|
Background tasks with hosted services in ASP.NET Core | guardrex | Learn how to implement background tasks with hosted services in ASP.NET Core. | >= aspnetcore-2.1 | riande | mvc | 06/03/2019 | fundamentals/host/hosted-services |
Background tasks with hosted services in ASP.NET Core
By Luke Latham
In ASP.NET Core, background tasks can be implemented as hosted services. A hosted service is a class with background task logic that implements the xref:Microsoft.Extensions.Hosting.IHostedService interface. This topic provides three hosted service examples:
- Background task that runs on a timer.
- Hosted service that activates a scoped service. The scoped service can use dependency injection.
- Queued background tasks that run sequentially.
View or download sample code (how to download)
The sample app is provided in two versions:
- Web Host – Web Host is useful for hosting web apps. The example code shown in this topic is from Web Host version of the sample. For more information, see the Web Host topic.
- Generic Host – Generic Host is new in ASP.NET Core 2.1. For more information, see the Generic Host topic.
::: moniker range=">= aspnetcore-3.0"
Worker Service template
The ASP.NET Core Worker Service template provides a starting point for writing long running service apps. To use the template as a basis for a hosted services app:
Visual Studio
- Create a new project.
- Select ASP.NET Core Web Application. Select Next.
- Provide a project name in the Project name field or accept the default project name. Select Create.
- In the Create a new ASP.NET Core Web Application dialog, confirm that .NET Core and ASP.NET Core 3.0 are selected.
- Select the Worker Service template. Select Create.
.NET Core CLI
Use the Worker Service (worker
) template with the dotnet new command from a command shell. In the following example, a Worker Service app is created named ContosoWorkerService
. A folder for the ContosoWorkerService
app is created automatically when the command is executed.
dotnet new worker -o ContosoWorkerService
::: moniker-end
Package
Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Hosting package.
IHostedService interface
Hosted services implement the xref:Microsoft.Extensions.Hosting.IHostedService interface. The interface defines two methods for objects that are managed by the host:
-
StartAsync(CancellationToken) –
StartAsync
contains the logic to start the background task. When using the Web Host,StartAsync
is called after the server has started and IApplicationLifetime.ApplicationStarted is triggered. When using the Generic Host,StartAsync
is called beforeApplicationStarted
is triggered. -
StopAsync(CancellationToken) – Triggered when the host is performing a graceful shutdown.
StopAsync
contains the logic to end the background task. Implement xref:System.IDisposable and finalizers (destructors) to dispose of any unmanaged resources.The cancellation token has a default five second timeout to indicate that the shutdown process should no longer be graceful. When cancellation is requested on the token:
- Any remaining background operations that the app is performing should be aborted.
- Any methods called in
StopAsync
should return promptly.
However, tasks aren't abandoned after cancellation is requested—the caller awaits all tasks to complete.
If the app shuts down unexpectedly (for example, the app's process fails),
StopAsync
might not be called. Therefore, any methods called or operations conducted inStopAsync
might not occur.To extend the default five second shutdown timeout, set:
- xref:Microsoft.Extensions.Hosting.HostOptions.ShutdownTimeout* when using Generic Host. For more information, see xref:fundamentals/host/generic-host#shutdown-timeout.
- Shutdown timeout host configuration setting when using Web Host. For more information, see xref:fundamentals/host/web-host#shutdown-timeout.
The hosted service is activated once at app startup and gracefully shut down at app shutdown. If an error is thrown during background task execution, Dispose
should be called even if StopAsync
isn't called.
Timed background tasks
A timed background task makes use of the System.Threading.Timer class. The timer triggers the task's DoWork
method. The timer is disabled on StopAsync
and disposed when the service container is disposed on Dispose
:
The service is registered in Startup.ConfigureServices
with the AddHostedService
extension method:
Consuming a scoped service in a background task
To use scoped services within an IHostedService
, create a scope. No scope is created for a hosted service by default.
The scoped background task service contains the background task's logic. In the following example, an xref:Microsoft.Extensions.Logging.ILogger is injected into the service:
The hosted service creates a scope to resolve the scoped background task service to call its DoWork
method:
The services are registered in Startup.ConfigureServices
. The IHostedService
implementation is registered with the AddHostedService
extension method:
Queued background tasks
A background task queue is based on the .NET 4.x xref:System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem* (tentatively scheduled to be built-in for ASP.NET Core 3.0):
In QueueHostedService
, background tasks in the queue are dequeued and executed as a xref:Microsoft.Extensions.Hosting.BackgroundService, which is a base class for implementing a long running IHostedService
:
The services are registered in Startup.ConfigureServices
. The IHostedService
implementation is registered with the AddHostedService
extension method:
In the Index page model class:
- The
IBackgroundTaskQueue
is injected into the constructor and assigned toQueue
. - An xref:Microsoft.Extensions.DependencyInjection.IServiceScopeFactory is injected and assigned to
_serviceScopeFactory
. The factory is used to create instances of xref:Microsoft.Extensions.DependencyInjection.IServiceScope, which is used to create services within a scope. A scope is created in order to use the app'sAppDbContext
(a scoped service) to write database records in theIBackgroundTaskQueue
(a singleton service).
When the Add Task button is selected on the Index page, the OnPostAddTask
method is executed. QueueBackgroundWorkItem
is called to enqueue the work item: