I would like to present how to make background services in asp.net core with IHostedService.
What is IHostedService
You can use IHostedService to create background tasks in asp.net core projects. I used Quartz.NET to similar purposes in the past. I do not want to compare them because it is not purpose of this article :-). So, if you want to create background task you can do that by implementing IHostedService. It’s very simple 🙂
How can we use it
I would like to create very very simple background task which creates GUIDs every 10 seconds and save them in memory cache. Don’t worry I’ll display them on website 😉 We need to create some base class BackgroundService. I create something similar like BackgroundService from here
BackgroundService:
[csharp]
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Letys.HostedService.Example.Services
{
public abstract class BackgroundService : IHostedService, IDisposable
{
private Task task;
private readonly CancellationTokenSource cancellationTokens = new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
this.task = this.ExecuteAsync(this.cancellationTokens.Token);
return this.task.IsCompleted ? this.task : Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (this.task != null)
{
try
{
this.cancellationTokens.Cancel();
}
finally
{
await Task.WhenAny(task, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
}
public virtual void Dispose()
{
this.cancellationTokens.Cancel();
}
}
}
[/csharp]
After that we can create our background task class – ExampleGuidService:
[csharp]
using Letys.HostedService.Example.Models;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Letys.HostedService.Example.Services
{
public class ExampleGuidService : BackgroundService
{
public const string ExampleGuidsKey = “ExampleGuids”;
private IMemoryCache memoryCache;
public ExampleGuidService(IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
GenerateNewExampleGuid();
await Task.Delay(1000*10, stoppingToken);
}
}
private void GenerateNewExampleGuid()
{
ExampleGuid example = new ExampleGuid
{
Timestamp = DateTime.Now,
Guid = Guid.NewGuid()
};
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(24));
if (!this.memoryCache.TryGetValue(ExampleGuidService.ExampleGuidsKey, out List
{
cacheEntry = new List
}
cacheEntry.Add(example);
this.memoryCache.Set(ExampleGuidService.ExampleGuidsKey, cacheEntry, cacheEntryOptions);
}
}
}
[/csharp]
This is our ExampleGuid:
[csharp]
using System;
namespace Letys.HostedService.Example.Models
{
public class ExampleGuid
{
public Guid Guid { get; set; }
public DateTime Timestamp { get; set; }
}
}
[/csharp]
We can register ExampleGuidService in Startup.cs:
[csharp]
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddMvc();
services.AddSingleton
}
[/csharp]
Now we can add ExampleGuids action and view:
[csharp]
public IActionResult ExampleGuids()
{
if (!this.memoryCache.TryGetValue(ExampleGuidService.ExampleGuidsKey, out List cacheEntry))
{
cacheEntry = new List();
}
return View(cacheEntry);
}
[/csharp]
[html]
@model IEnumerable
@{
ViewData[“Title”] = “ExampleGuids”;
Layout = “~/Views/Shared/_Layout.cshtml”;
}
ExampleGuids
@Html.DisplayNameFor(model => model.Guid) | @Html.DisplayNameFor(model => model.Timestamp) |
---|---|
@Html.DisplayFor(modelItem => item.Guid) | @Html.DisplayFor(modelItem => item.Timestamp) |
[/html]
As you can see every 10 seconds ExampleGuidService creates new guid.