Implement Background Task Using BackgroundService Class In ASP.NET Core


If you are new in background task implementation using Background Service class then please read below article so you will get a better understanding for this BackgroundService class in this article with an example.
In this above article, you will get an idea exactly what is BackgroundService and IHostedService. For the implementation of the background task, we dont need any Nuget packages or anything et. It is in core ASP.NET infrastructure itself. We know that the background tasks can be implemented in main two ways in ASP.NET core using BackgroundService Class and IHostedService. BackgroundService class is nothing but an abstract base class.BackgroundService class was present in ASP.NET Core 3.0.It is an abstract base class for implementing long-running services.Using BackgroundService class we can only have one method that needs to be implemented which is ExecuteAsync(CancellationToken cancellationtoken).StartAsync and StopAsync are virtual so you could override it. The default behavior of BackgroundService class is that StartAsync calls ExecuteAsync.If you create a subclass of a BackgroundService, you must implement ExecuteAsync (Because of its Abstract).
Let's see this with the below example.
In the below example, we are trying to check the status of particular URL, when it is up and when it is down after a specific period of time. If it is up, then we need to write it down in a .txt file, and when it is down, also have it written in a .txt file.
Step 1
As you can see in below diagram, the BackgroundService class has been implemented:
  1. private readonly ILogger<Worker> _logger;  
  2. private HttpClient httpClient;  
  3. public Worker(ILogger<Worker> logger)  
  4. {  
  5.     _logger = logger;  
  6. }  
  8. public override Task StartAsync(CancellationToken cancellationToken)  
  9. {  
  10.     httpClient = new HttpClient();  
  11.     return base.StartAsync(cancellationToken);    
  12. }  
  14. public override Task StopAsync(CancellationToken cancellationToken)  
  15. {  
  16.     httpClient.Dispose();  
  17.     return base.StopAsync(cancellationToken);  
  18. }  
As you can see in the above diagram, in the constructor we initialize a logger for logging output. We also define HttpClient which is a base class for sending HTTP requests and HTTP responses identified by a URI. As you see we implement two methods above StartAsync andStopAsync for our requirement which we need to achieve. Our target is only to run background service and capturing and maintaining status for a particular URL.HttpClient does indirectly implement IDisposable interface the standard usage of HttpClient is not to dispose of it after every request. It releases unmanaged resources used by the HttpClient and optionally disposes of the managed resources.
Step 2
In the below diagram, as you can see the ExecuteAsync method implementation has main logic.
  1. protected override async Task ExecuteAsync(CancellationToken stoppingToken)  
  2.         {  
  3.             while(!stoppingToken.IsCancellationRequested)  
  4.             {  
  5.                 try  
  6.                 {  
  7.                     var result = await httpClient.GetAsync("");  
  8.                     if (result.IsSuccessStatusCode)  
  9.                     {  
  10.                         _logger.LogInformation("The Website is Up.Status Code {StatusCode}", result.StatusCode);  
  11.                     }  
  12.                     else  
  13.                     {  
  14.                         _logger.LogError("The Website is Down.Status Code {StatusCode}", result.StatusCode);  
  15.                     }  
  16.                 }  
  17.                 catch(Exception ex)  
  18.                 {  
  19.                     _logger.LogError("The Website is Down {0}.", ex.Message);  
  20.                 }  
  21.                 finally  
  22.                 {  
  23.                     await Task.Delay(1000 * 5, stoppingToken);  
  24.                 }  
  26.                     //_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);  
  28.             }  
  29.         }  
As you can see above, I tried to check the status for this URL, every 5 seconds for when it is up and when it is down.
Step 3
As you can see in the below diagram, you need to install Serilog from Nuget for writing texts into a textfile.
There are two packages which you need:
  • Serilog.AspNetCore
  • Serilog.Sinks.File
Step 4
In the below diagram, you will see I defined a path where our file was stored. In this file, we will get the status of our URL, if it is running or down every 5 seconds.
  1. public static void Main(string[] args)  
  2.         {  
  3.             Log.Logger = new LoggerConfiguration()  
  4.                             .MinimumLevel.Debug()  
  5.                             .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)  
  6.                             .Enrich.FromLogContext()  
  7.                             .WriteTo.File(@"C:\Service\LogFile.txt")  
  8.                             .CreateLogger();  
  9.             try  
  10.             {  
  11.                 Log.Information("Starting up the Service");  
  12.                 CreateHostBuilder(args).Build().Run();  
  13.                 return;  
  14.             }  
  15.             catch(Exception ex)  
  16.             {  
  17.                 Log.Fatal(ex,"There was a problem starting Service");  
  18.                 return;  
  19.             }  
  20.             finally  
  21.             {  
  22.                 Log.CloseAndFlush();  
  23.             }  
  25.             //CreateHostBuilder(args).Build().Run();  
  26.         }  
Step 5
This is the last step where you will configure your service with Dependency Injection.
  1. public static IHostBuilder CreateHostBuilder(string[] args) =>  
  2.             Host.CreateDefaultBuilder(args)  
  3.                 .ConfigureWebHostDefaults(webBuilder =>  
  4.                 {  
  5.                     webBuilder.UseStartup<Startup>();  
  6.                 }).ConfigureServices(services =>  
  7.                    services.AddHostedService<Worker>())  
  8.                             .UseSerilog();  
I hope you will understand this article of BackgroundService Class with an example. Let me know if you are facing any issues while implementing this kind of application. In our next article, we will see a Background Task using IHostedService.