Background Services with C#

Background Services with C#

Background services, often referred to as background workers or daemons, are critical components of modern software applications. Unlike regular user-facing programs, these services operate silently in the background, performing tasks independently of user interaction. They are responsible for various essential tasks, such as data synchronization, email notifications, periodic updates, and much more.

Key Benefits of Background Services

  1. Enhanced Performance: Background services help offload time-consuming tasks from the main application thread, ensuring smooth user experiences even during resource-intensive operations.

  2. Automation: By running in the background, these services automate repetitive processes, reducing manual intervention and potential errors.

  3. Scalability: Background services allow developers to efficiently handle large-scale operations, making it easier to manage growing user bases and increased data loads.

  4. Real-time Updates: They enable real-time data synchronization and ensure that information is always up to date, providing users with the latest insights.

Creating Background Services in C

GitHub

Step 1: Set Up the Project

Start by creating a new ASP.NET Core Web Api application.

Step 2: Define the Background Service

Create a new class that inherits from the BackgroundService base class. This class will encapsulate the logic of your background service. In this example, we are going to create two classes, one for a simple execution task, and the other for a periodic execution.

Step 3: Implement the ExecuteAsync Method

Override the ExecuteAsync method within your background service class. This method will contain the main tasks that the background service performs. Ensure that you implement cancellation handling and follow best practices for long-running tasks.

public class SimpleService : BackgroundService
{
    private readonly ILogger<SimpleService> logger;
    public SimpleService(ILogger<SimpleService> logger)
    {
        this.logger = logger;
    }
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var numberOfThreads = Process.GetCurrentProcess().Threads.Count;

        logger.LogInformation($"Task executed. Numer of Threads: {numberOfThreads}");
        await Task.CompletedTask;
    }
}
public class PeriodicService : BackgroundService
{
    private readonly ILogger<PeriodicService> logger;
    private readonly TimeSpan period = TimeSpan.FromSeconds(5);
    public PeriodicService(ILogger<PeriodicService> logger)
    {
        this.logger = logger;
    }
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using PeriodicTimer timer = new PeriodicTimer(period);

        while (!stoppingToken.IsCancellationRequested &&
               await timer.WaitForNextTickAsync(stoppingToken))
        {
            logger.LogInformation("Executing PeriodicBackgroundTask");
        }
    }
}

Step 4: Register the Background Service

In the ConfigureServices method of the Startup class (Program.cs), register your background service using the IServiceCollection.AddHostedService method.

builder.Services.AddHostedService<SimpleService>();
builder.Services.AddHostedService<PeriodicService>();

Step 5: Run the Application

With your background service registered, run the application, and your background service will start executing asynchronously.

Best Practices for Background Services

  1. Proper Error Handling: Implement robust error handling mechanisms to handle exceptions gracefully and log errors appropriately to aid in debugging.

  2. Use Dependency Injection: Leverage dependency injection to manage the services and resources that your background service requires.

  3. Avoid Blocking Operations: Ensure that your background service does not perform blocking operations to prevent bottlenecks and slowdowns.

  4. Implement Cancellation Tokens: Use CancellationTokenSource to allow graceful shutdown and cancellation of background tasks.

  5. Thoroughly Test Your Service: Test your background service in different scenarios and edge cases to identify and rectify potential issues before deployment.

Did you find this article valuable?

Support Guillermo Valenzuela's blog by becoming a sponsor. Any amount is appreciated!