Take advantage of the IHostedService interface in ASP.Net Core to build and run background tasks or hosted services Credit: Thinkstock When developing web applications, you will often need to schedule and run background tasks. The IHostedService interface in ASP.Net Core provides a simple way to implement services that execute in the background. In this post we will explore how we can use this interface to implement background tasks, aka “hosted services,” in ASP.Net Core. The IHostedService interface was introduced in ASP.Net Core 2.0. Here is a look at this interface. public interface IHostedService { // // Summary: // Triggered when the application host is ready to start the service. Task StartAsync(CancellationToken cancellationToken); // // Summary: // Triggered when the application host is performing a graceful shutdown. Task StopAsync(CancellationToken cancellationToken); } Implement the IHostedService interface When implementing the IHostedService interface, we will have to implement two methods in our code. These include the StartAsync() and StopAsync() methods; the former is called at startup, the latter is called at shutdown. Note that the implementations will vary depending on the background processing we want to execute. In this example, we will take advantage of the following abstract base class created by Microsoft’s David Fowler. 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); } Extend the base class and implement ExecuteAsync Now that this base class is available, all we need to do is extend this class and implement the ExecuteAsync method. Let’s do that by creating our own IDGBackgroundService class, shown in the code snippet below. public class IDGBackgroundService : HostedService { protected override async Task ExecuteAsync(CancellationToken cancellationToken) { //Write your custom implementation here } } Our IDGBackgroundService will read data from an external data source every 60 seconds and update a log file accordingly. Of course you could make this duration configurable, or write your own custom implementation for the service. Below is the updated version of the IDGBackgroundService class that illustrates how the ExecuteAsync method is implemented. Note that the ExecuteAsync method accepts a cancellation token as a parameter. public class IDGBackgroundService : HostedService { private readonly IDGDataProvider _dataProvider; public DataRefreshService(IDGDataProvider dataProvider) { _dataProvider = dataProvider; } protected override async Task ExecuteAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { await _dataProvider.UpdateLogFile(cancellationToken); await Task.Delay(TimeSpan.FromSeconds(60), cancellationToken); } } } As you see in the code snippet above, the IDGDataProvider class reads data from an external data source and then stores the data retrieved in a log file. Below you can see what this class would look like. I will leave the implementation blank here, but you can take a look at my article on building a custom logger. public class IDGDataProvider { public async Task UpdateLogFile(CancellationToken cancellationToken) { //Write your own implementation here } //Other members } Wire up our service classes with dependency injection Lastly, we should wire up our service using dependency injection so that it will start automatically when our application is started. To do this, we will need to add the service in the ConfigureServices method of the Startup class as shown below. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSingleton<IDGDataProvider>(); services.AddSingleton<IHostedService, IDGBackgroundService>(); } The IHostedService interface in ASP.Net Core provides a nice and simple way to implement background tasks in a web application. Any hosted services that you will build by implementing this interface should be registered at startup using dependency injection. You can take advantage of the IHostedService interface to spin up multiple tasks while at the same time ensuring that such tasks will shut down gracefully whenever the web host shuts down. Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos