Is the following a correct pattern to implement long running background work in Asp.Net Core? Or should I be using some form of Task.Run
/TaskFactory.StartNew
with TaskCreationOptions.LongRunning
option?
public void Configure(IApplicationLifetime lifetime)
{
lifetime.ApplicationStarted.Register(() =>
{
// not awaiting the 'promise task' here
var t = DoWorkAsync(lifetime.ApplicationStopping);
lifetime.ApplicationStopped.Register(() =>
{
try
{
// give extra time to complete before shutting down
t.Wait(TimeSpan.FromSeconds(10));
}
catch (Exception)
{
// ignore
}
});
});
}
async Task DoWorkAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
await // async method
}
}
Check also .NET Core 2.0 IHostedService
. Here is the documentation. From .NET Core 2.1 we will have BackgroundService
abstract class.
It can be used like this:
public class UpdateBackgroundService: BackgroundService
{
private readonly DbContext _context;
public UpdateTranslatesBackgroundService(DbContext context)
{
this._context= context;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await ...
}
}
In your startup you just have to register class:
public static IServiceProvider Build(IServiceCollection services)
{
//.....
services.AddSingleton<IHostedService, UpdateBackgroundService>();
services.AddTransient<IHostedService, UpdateBackgroundService>(); //For run at startup and die.
//.....
}
Is the following a correct pattern to implement long running background work in Asp.Net Core?
Yes, this is the basic approach to start long-running work on ASP.NET Core. You should certainly not use Task.Run
/StartNew
/LongRunning
- that approach has always been wrong.
Note that your long-running work may be shut down at any time, and that's normal. If you need a more reliable solution, then you should have a separate background system outside of ASP.NET (e.g., Azure functions / AWS lambdas). There are also libraries like Hangfire that give you some reliability but have their own drawbacks.
Update: I've written a blog series on how to implement the more reliable approach, using a durable queue with a separate background system. In my experience, most developers need the more reliable approach because they don't want their long-running work to be lost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With