Skip to content

Instantly share code, notes, and snippets.

@davidfowl
Created July 17, 2017 09:31
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save davidfowl/a7dd5064d9dcf35b6eae1a7953d615e3 to your computer and use it in GitHub Desktop.
Save davidfowl/a7dd5064d9dcf35b6eae1a7953d615e3 to your computer and use it in GitHub Desktop.
A base class that allows writing a long running background task in ASP.NET Core 2.0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
namespace WebApplication24
{
public abstract class HostedService : IHostedService
{
private Task _executingTask;
private CancellationTokenSource _cts;
public Task StartAsync(CancellationToken cancellationToken)
{
// Create a linked token so we can trigger cancellation outside of this token's cancellation
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
// Store the task we're executing
_executingTask = ExecuteAsync(_cts.Token);
// If the task is completed then return it
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
// Signal cancellation to the executing method
_cts.Cancel();
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
// Throw if cancellation triggered
cancellationToken.ThrowIfCancellationRequested();
}
// Derived classes should override this and execute a long running method until
// cancellation is requested
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
}
}
@davidfowl
Copy link
Author

@vitidev
Copy link

vitidev commented May 7, 2019

Is cancellationToken.ThrowIfCancellationRequested(); in StopAsync necessary?

HostedServiceExecutor doesn't catch OperationCancelledException and we get a lot of errors in console

 Application started. Press Ctrl+C to shut down.
 Application is shutting down...
 crit: Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor[10]
 An error occurred stopping the application
 System.AggregateException: One or more errors occurred. (The operation was canceled.)  (The operation was canceled.) (The operation was canceled.) ---> System.OperationCanceledException: The operation was canceled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment