Dot Net Core 7 — Run Periodic Background tasks
To run background tasks in Dot Net Core on periodic basis ( at regular intervals), make use of BackgroundService base class.
Introduction
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 IHostedService interface.
The IHostedService interface contains two methods:
- StartAsync — Triggered when the application host is ready to start the service
- StopAsync — Executed when app is running shutdown and also dispose the resources (unmanaged)
In this article I am going to explain Periodic Background tasks by making use of BackgroundService base class
BackgroundService base class
Background Service base class is used to implement hosted service interface.
This base class defines below method:
ExecuteAsync— This method is called when the IHostedService starts. The implementation should return a task that represents the lifetime of the long running operation(s) being performed.
Periodic Background Hosted Service
This service class override the ExecuteAsync method and add logic to periodically run the tasks in background by make use of PeriodicTimer class.
PeriodicTimer — Provides a periodic timer that enables waiting asynchronously for timer ticks. This timer is intended to be used only by a single consumer at a time, only one call to WaitForNextTickAsync
Lets do step by step implementation
- Create a PeriodicHostedService class and inherit BackgroundService base class. Inject all the required dependencies and implement the method ExecuteAsync as below:
2. Extend the ExecuteAsync method and add Periodic Timer to run the task at regular intervals as below:
3. Create required scope & call your custom method to perform task. In my case, I have to send notification every 60 seconds, so I created Notification Service class and send notification as below:
4. Scoped the services as PeriodicHostedService & NotificationService in Program.cs file as below:
5. Run the application and every 60 seconds (configured) you will get the notification.
C# Code:
public class PeriodicHostedService : BackgroundService
{
private readonly ILogger<PeriodicHostedService> _logger;
private readonly IServiceScopeFactory _factory;
private readonly IConfiguration _configuration;
private int _executionCount = 0;
public bool IsEnabled { get; set; }
public PeriodicHostedService(
ILogger<PeriodicHostedService> logger,
IServiceScopeFactory factory, IConfiguration configuration)
{
_logger = logger;
_factory = factory;
_configuration = configuration;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
int period = 60; // in seconds or set as per your need
using PeriodicTimer timer = new PeriodicTimer(TimeSpan.FromSeconds(period));
while (
!stoppingToken.IsCancellationRequested &&
await timer.WaitForNextTickAsync(stoppingToken))
{
try
{
await using AsyncServiceScope asyncScope = _factory.CreateAsyncScope();
NotificationService notificationService = asyncScope.ServiceProvider.GetRequiredService<NotificationService>();
await notificationService.SendNotification();
_executionCount++;
_logger.LogInformation(
$"Executed PeriodicHostedService - Count: {_executionCount}");
}
catch (Exception ex)
{
_logger.LogInformation(
$"Failed to execute PeriodicHostedService with exception message {ex.Message}. Good luck next round!");
}
}
}
}