Background Services Made Easy in .NET
If you’ve ever needed to run background tasks in your .NET applications, you’ll love how easy it is with LINQPad and .NET’s hosting model. LINQPad makes it simple to experiment with background services, letting you see results instantly and understand how everything fits together—before you add it to your production code.
.NET’s IHostedService
interface is the key to running long-lived background processes, whether you’re building an ASP.NET Core website, a console app, or something else. By using a Generic or Web Host, you can add background processing that starts and stops automatically with your application.
One of the best parts? LINQPad lets you test these services interactively. You can see how background tasks behave, how they respond to cancellation, and how dependency injection works—all in real time.
Here’s a practical example you can try in LINQPad. This code sets up a background service that logs a message every five seconds. It uses .NET’s BackgroundService
base class and the new PeriodicTimer
for easy scheduling. Everything is wired up with dependency injection, just like in a real app:
async Task Main()
{
// supercharge your .NET development
// https://www.learninglinqpad.com
// var builder = WebApplication.CreateBuilder(); ... works here too!!
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
builder.Services.AddHostedService<BGService>();
builder.Services.AddSingleton<DumpContainerService>(sp => new DumpContainerService("LearningLinqpad.com"));
IHost app = builder.Build();
// linqpad provides a CancellationToken to each query
// now the host is timed perfectly to the linqpad query lifetime
await app.RunAsync(QueryCancelToken);
}
public class BGService : BackgroundService
{
private readonly DumpContainerService _dcs;
public BGService(DumpContainerService dcs)
{
_dcs = dcs;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using PeriodicTimer _timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
while (await _timer.WaitForNextTickAsync(stoppingToken))
{
_dcs.Output(new { logging = "ExecuteAsync called" });
}
}
public override Task StartAsync(CancellationToken stoppingToken)
{
base.StartAsync(stoppingToken);
_dcs.Output("BGService is starting.");
return Task.CompletedTask;
}
public override Task StopAsync(CancellationToken stoppingToken)
{
base.StopAsync(stoppingToken);
_dcs.Output("BGService is stopping.");
return Task.CompletedTask;
}
}
public class DumpContainerService
{
private readonly DumpContainer dc = null;
public DumpContainerService(string name)
{
dc = new DumpContainer();
dc.Dump(name);
}
public void Output(object o) { dc.AppendContent(o); }
}
Download LINQPad Today
Get started with the most powerful .NET Rapid Progress Tool (RPT) available.
Get LINQPad PremiumPowerful .NET acceleration. Code at the speed of thought.
With this setup, you can:
- Run background jobs like sending emails, refreshing caches, or polling external services.
- Handle graceful shutdowns with built-in support for
CancellationToken
. - Use full dependency injection, just like in ASP.NET Core.
LINQPad makes it easy to learn and test these concepts. You can see how your background services behave, tweak the code, and understand the flow—without waiting for a full deployment.
Want to learn more about LINQPad and how it can supercharge your development workflow? Check out my comprehensive LINQPad course where I cover everything from basic queries to advanced scenarios like the ones shown here.