Introduction

Not every task in an application needs to be completed while a user is waiting for a response. Some operations, such as sending emails, generating reports, processing files, or cleaning up old data, can run in the background without affecting the user experience.

This is where .NET Worker Services are useful. They allow developers to build long-running background processes that operate independently of web requests. Worker Services are lightweight, scalable, and well-suited for cloud, on-premises, and containerized environments.

In this article, you'll learn what .NET Worker Services are, how they work, and how to build a simple background processing service.

What Are .NET Worker Services?

A .NET Worker Service is a background application designed to run continuously or execute scheduled tasks without requiring user interaction.

Unlike an ASP.NET Core Web API, which responds to HTTP requests, a Worker Service performs tasks in the background.

Common examples include:

Worker Services use the .NET Generic Host, which provides built-in support for dependency injection, logging, and configuration.

Why Use Worker Services?

Worker Services offer several advantages for background processing:

Separating background tasks from your main application also makes the overall system easier to maintain and scale.

Creating a Worker Service

You can create a new Worker Service using the .NET CLI.

dotnet new worker -n BackgroundWorkerDemo

This command creates a project with the basic files needed for a background service.

The generated project already includes a sample worker class that runs continuously until the application stops.

Understanding the Worker Class

The main background logic is placed inside a class that inherits from BackgroundService.

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("Background task is running.");

            await Task.Delay(5000, stoppingToken);
        }
    }
}

In this example:

Practical Example

Imagine you're building an e-commerce application.

When a customer places an order, several tasks need to happen:

Instead of making the customer wait for all these operations to complete, the API can save the order immediately and let a Worker Service handle the remaining tasks in the background.

This improves response times and provides a better user experience.

Using Dependency Injection

Like ASP.NET Core applications, Worker Services support dependency injection.

For example, you can inject a service into your worker.

public class Worker : BackgroundService
{
    private readonly IEmailService _emailService;

    public Worker(IEmailService emailService)
    {
        _emailService = emailService;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // Background processing logic
    }
}

This approach keeps your code modular and makes it easier to test and maintain.

Common Use Cases

Worker Services are commonly used for:

These tasks typically don't require an immediate response to the user, making them ideal for background processing.

Error Handling

Background services should be designed to handle unexpected errors gracefully.

Consider these practices:

Proper error handling helps keep your background processes reliable over time.

Best Practices

When building Worker Services, follow these recommendations:

These practices improve scalability, maintainability, and reliability.

Things to Consider

Before deploying a Worker Service, keep the following in mind:

Planning for these scenarios helps create a stable and resilient background processing system.

Conclusion

.NET Worker Services provide a simple and effective way to build background processing applications. They allow developers to move time-consuming tasks out of the request pipeline, improving application performance and creating a better experience for users.

Whether you're processing messages, sending emails, generating reports, or synchronizing data, Worker Services offer a reliable foundation for long-running operations. By following best practices such as using dependency injection, handling errors gracefully, and respecting cancellation tokens, you can build scalable and maintainable background services that integrate seamlessly with modern .NET applications.