Introduction
Worker services in .NET Core have emerged as a powerful mechanism for building background services that run continuously and perform various tasks. This blog provides a step-by-step guide on creating worker services, delving into their evolution, and elucidating the code snippets along with the execution process.
Evolution of Worker Services
Worker services represent a continuation of the .NET Core journey, evolving from the need to run background tasks efficiently. They inherit concepts from hosted services and console applications, offering a robust solution for scenarios where continuous execution is required, such as data processing, message queue consumption, or scheduled tasks.
Step 1. Create a Worker Service
Begin by creating a new worker service project using the .NET CLI
dotnet new worker -n MyWorkerService
This command generates the basic structure for a worker's service.
Step 2. Define Worker Logic
Navigate to the generated Worker.cs
file. Here, you can define the logic that your worker service will execute continuously. For example.
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
In this example, the worker logs a message every second. You can replace this logic with your specific requirements.
Step 3. Configure and Run the Worker
Navigate to the Program.cs
file and configure the worker service within the CreateHostBuilder
method
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
This configuration registers the worker service to be managed by the host.
Step 4. Run the Worker Service
Build and run the worker service using the following commands
dotnet build
dotnet run
The worker service will start running, and you'll see log messages being generated at the specified interval.
Step 5. Execution Process
The ExecuteAsync
method within the worker service is the entry point for the continuous execution process. It runs until the cancellation token signals a shutdown request. The Task.Delay
ensures the specified delay between iterations.
Schedule Runs
Understanding how to schedule tasks at specific intervals or times enhances the versatility of worker services. Follow this step-by-step guide to incorporate scheduling into your .NET Core worker service.
Install Required Packages
To enable scheduling, you'll need the Quartz
library. Install it using the following command
dotnet add package Quartz
Define a Scheduled Job
Create a class for the job you want to schedule. For example, a job that runs every hour
public class HourlyJob : IJob
{
private readonly ILogger<HourlyJob> _logger;
public HourlyJob(ILogger<HourlyJob> logger)
{
_logger = logger;
}
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Hourly job executed at: {time}", DateTimeOffset.Now);
}
}
Configure Quartz
In the ConfigureServices
method of Startup.cs
, configure Quartz to use the JobScheduler.
services.AddSingleton(provider =>
{
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler().Result;
scheduler.Start();
var job = JobBuilder.Create<HourlyJob>()
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity("hourlyTrigger", "default")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInHours(1).RepeatForever())
.Build();
scheduler.ScheduleJob(job, trigger);
return scheduler;
});
This configuration sets up a job (HourlyJob
) to run every hour.
Modify Worker Service
Update the Worker.cs
to inject the Quartz scheduler and handle its lifecycle.
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IScheduler _scheduler;
public Worker(ILogger<Worker> logger, IScheduler scheduler)
{
_logger = logger;
_scheduler = scheduler;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await _scheduler.Shutdown();
await base.StopAsync(cancellationToken);
}
}
Run the Application
Build and run the application using the following commands.
dotnet build
dotnet run
Now, you'll see the worker service logging every second and the hourly job executing at the specified interval.
Conclusion
Creating a worker service in .NET Core is a straightforward process, offering a versatile solution for background task execution. The evolution from hosted services and console applications has resulted in a framework that seamlessly integrates with the broader .NET ecosystem. By following this step-by-step guide, you can build and run your worker service, gaining hands-on experience in the world of background task management in .NET Core.
By integrating scheduling into your .NET Core worker service using Quartz, you can extend its functionality to include frequent runs, such as hourly tasks. This step-by-step guide demonstrates the seamless integration of Quartz and worker services, providing you with a powerful toolset for managing background tasks. As you explore this enhanced capability, consider adapting the scheduling logic to suit your specific requirements, such as daily, weekly, or custom intervals.
Happy coding!