Background Tasks & Hosted Services in ASP.NET Core

Not everything happens in a request-response cycle. Sometimes you need to run jobs in the background like sending emails, processing queues, or cleaning up logs. That’s where Hosted Services in ASP.NET Core come in.

Let’s learn how to create background tasks the right way.


🧠 What Is a Hosted Service?

A hosted service is a background task that runs alongside your app. It can:

  • 🕓 Run on a schedule (like a cron job)
  • 🕵️ Monitor queues or databases
  • 🔁 Perform recurring tasks

You implement it via the IHostedService interface or inherit from BackgroundService.


🛠️ Basic Example Using BackgroundService

public class HeartbeatService : BackgroundService
{
    private readonly ILogger<HeartbeatService> _logger;

    public HeartbeatService(ILogger<HeartbeatService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Heartbeat at: {time}", DateTimeOffset.Now);
            await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
        }
    }
}

Register it in Program.cs:

builder.Services.AddHostedService<HeartbeatService>();

📦 Use Cases

  • 📨 Sending emails/SMS
  • 🧹 Cleaning expired records
  • 🔄 Pulling data from external APIs
  • 🧾 Generating periodic reports

🧪 Testing Cancellation

ASP.NET Core gracefully shuts down hosted services when the app exits.

Use the stoppingToken in loops to detect shutdown and exit cleanly.


⏱️ Want Scheduling? Use Hangfire or Quartz.NET

For cron-like scheduled jobs:

🔹 Hangfire

dotnet add package Hangfire

Configure:

builder.Services.AddHangfire(x => x.UseSqlServerStorage("YourConnectionString"));
builder.Services.AddHangfireServer();

Define jobs:

RecurringJob.AddOrUpdate(() => Console.WriteLine("Run every minute"), Cron.Minutely);

Visit /hangfire dashboard for job status.


⚠️ Tips & Gotchas

  • Avoid blocking calls (Thread.Sleep) — always use await Task.Delay
  • Use scoped services with IServiceScopeFactory
  • Log exceptions — don’t let them crash your worker silently

✅ Up Next

We’ve gone behind the scenes. Next: Let’s deploy to the cloud — Azure, AWS, or Docker!

➡️ Deploying ASP.NET Core to the Cloud →

Background magic, done right ✨

0
Subscribe to my newsletter

Read articles from Esanju Babatunde directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Esanju Babatunde
Esanju Babatunde