
Perform Background Workloads in Hosted Service using Channels in ASP.NET Web API
webapi
12 Articles
In this article, let's learn about how to perform background workloads with the help of Channels
inside
Hosted Service
in WebAPI
in ASP.NET Core.
Table of Contents
- Introduction
- What are Channels?
- What is Hosted Service?
- Performing Background Workloads in Hosted Service
- Summary
Introduction
I got an requirement to do data migration from one of my client and the constraint they have is to do it via an endpoint in web api
. Initially I thought it might be simple data migration but then I realized that it is not just a simple data migration but it is
a huge data migration. Though we recommended alternate approached the client was not ready to touch production database data outside the application.
So we decided to do it via an web api endpoint. But the problem is that the data migration will take more than 30 minutes to complete and the request
will timeout. So upon further analysis I came to know about Channels
and
Hosted Service
in ASP.NET Core. Before we start lets understand what are channels and hosted service. This
problem provides an example of a potential use case for a hosted service.
Other use cases include:
Processing uploaded excel in background
Sending emails in background
Other long running operations
, etc
What are Channels ?
A channel is a synchronisation concept which supports passing data between producers
and
consumers
concurrently
. One or many producers can
write
data into the channel, which are then read
by one or many consumers.
Logically a channel is effectively an efficient, thread-safe queue
. Channels are available under
System.Threading.Channels
namespace
To know more about Channels
is outside the scope of this article. I'll write a separate article on channels in
ASP.NET Core. For now lets walkthrough how to use Channels.
Code Sample - Data Migration Channel
In the above code, the DataMigrationChannel
class
provides a
bounded channel
for communication between producers
and
consumers
. Producers can add items to the channel using the MigrateData
method, and consumers can read all the items from the channel asynchronously
using the
ReadAllAsync
method. The class ensures that only one writer and one reader
can access the channel at a time and provides a limit on the number of messages that can be stored in the channel.
What is Hosted Service ?
Hosted services
in ASP.NET Core have been available since version 2.1
, and
they support performing background tasks outside of the main requests flow
. The best way to understand when and
where hosted services can be applied is to begin using them. In this article, we'll dive straight in and create our first hosted service. Hosted
services are based on the abstract
concept of a background service
. The
terms hosted service
and background service
are often used interchangeably.
I'll refer to them by both names throughout this article. Hosted services are available under
Microsoft.Extensions.Hosting
namespace.
To know more about Hosted Service
or Background Service
is outside the scope
of this article. I'll write a separate article on Background Services in ASP.NET Core. For now lets understand walkthrough how to use Hosted Service.
Code Sample - Data Migration Hosted Service
In the above code, the DataMigrationService
class
extends
BackgroundService
and is responsible for executing data migration tasks asynchronously
in the background. It reads items from the dataMigrationChannel
using an
IAsyncEnumerable<bool>
, performs the migration logic, and logs information about the start and completion of the
migration using the provided logger. The service relies on dependency injection
to access the necessary dependencies,
such as the DataMigrationChannel
, logger
, and
service provider
.
Performing Background Workloads in Hosted Service
So far we learn't what are channels and hosted service. Now lets see how to coordinate request and hosted service to perform background workloads.
We'll use System.Threading.Channels
to transfer data between requests and hosted
services. Our goal will be to offload a long-running processing workload to a hosted service so that we improve the response time for requests
received. The user will simply make a request to the API, the API will register a request in Channels and the API will return a response immediately.
The hosted service will then process the request in the background.
Before we look at the endpoint code, we need to register the Channel and Hosted Service in the Program
class
as shown below. Note that DataMigrationChannel
needs to be registered as
Singleton
service.
Note: If you have not done so already, I recommend you read the article on Dependency Injection Lifetimes in .NET.
Code Sample - Registering Hosted Service and Channel
Code Sample - Coordinating Request and Hosted Service
In the above code, the DataMigration
class
represents an
API controller
for handling data migration requests. It exposes a single
HTTP PUT
action method that triggers the data migration
process by invoking
the MigrateData
method on the injected DataMigrationChannel
instance.
Summary
In this article we learn't how to perform background workloads outside request life cycle using channels in hosted services in ASP.NET web api. We started with use case and under stood alternate use cases and then we learn't what are channels and hosted service. Then we learn't how to coordinate request and hosted service to perform background workloads. I hope you enjoyed reading this article. Now it's time to extend the idea like connecting producer and consumer via cloud and start implementing for similar use cases in your projects.