Background Services & Workers
In this lesson, you will learn how .NET background services and worker processes handle tasks that run outside the normal request-response flow. These are essential for recurring jobs, queue processing, cleanup routines, and many cloud-based workloads.
← Back to Visual Studio 2026 Tutorial HomeWhat you will learn
- What background services are and how they differ from request-based code
- How the
BackgroundServicebase class works - How to build safe processing loops with cancellation support
- How to handle errors, retries, and logging in background tasks
- How worker services fit into modern application architecture
Part 1: What is a background service?
A background service is a task that continues running after the application starts. Unlike controller actions or page handlers, it is not triggered directly by a user request. Instead, it performs ongoing or repeated work behind the scenes.
Common examples include:
- Processing messages from a queue
- Sending pending emails or notifications
- Refreshing cached data regularly
- Running scheduled reporting tasks
- Monitoring external systems and syncing data
Part 2: Using BackgroundService
The most common way to create a worker in .NET is to inherit from BackgroundService and implement ExecuteAsync. This gives you a clear lifecycle and integrates well with hosting and dependency injection.
This pattern is simple and effective, but it must be designed carefully so the loop does not become unstable, noisy, or wasteful.
Part 3: Cancellation and graceful shutdown
Background services should stop cleanly when the application shuts down. That is why the CancellationToken passed into ExecuteAsync is so important.
- Use the token in delays and external calls
- Exit the loop when cancellation is requested
- Avoid ignoring the token in long-running operations
- Release resources and stop accepting new work when shutting down
A service that ignores cancellation can delay application shutdown or leave background work in an unpredictable state.
Part 4: Error handling and retries
Background tasks often depend on networks, databases, queues, or APIs, which means failures are normal. A well-designed worker should expect temporary problems and respond carefully.
| Concern | Recommended approach |
|---|---|
| Temporary API failure | Retry with delay or backoff |
| Unexpected exception | Log clearly and prevent silent failure |
| Repeated failure | Escalate, alert, or move work aside for later review |
| Bad input data | Handle separately instead of crashing the worker loop |
Part 5: Scheduled work vs queue-based work
Not all background processing looks the same. Some workers run on a timer, while others respond to new work from a queue or stream.
- Scheduled worker: useful for recurring cleanup, reporting, or synchronization
- Queue worker: useful when tasks arrive unpredictably and should be processed as they come
- Continuous monitor: useful for watching system health or external feeds
Choosing the right model helps keep the application efficient and easier to reason about.
When to use a worker service
| Scenario | Why a worker is useful |
|---|---|
| Email sending | Removes delay from user-facing requests |
| Queue processing | Lets background jobs be handled independently |
| Recurring refresh tasks | Keeps data or cache updated regularly |
| External synchronization | Handles long-running integration tasks safely |
A practical worker workflow
Best practices
- Do not block threads unnecessarily inside worker loops
- Use cancellation tokens consistently
- Keep background responsibilities focused
- Log enough detail to diagnose failures later
- Design for temporary external failures
- Prefer graceful shutdown over forced interruption
Summary
In this lesson, you learned how background services and worker processes handle long-running or recurring tasks, why cancellation and resilience matter, and how to design workers that fit modern .NET systems.
In the next lesson, you will move into authentication and authorization.