August 19, 2021

.NET Core Worker Service - Implementing by BackgroundService

In this post we will see an example how to define Worker Service by inheriting the BackgroundService abstract base class.

I am using Visual Studio 2019 Community Edition and .Net Core framework 3.1. Lets start creating new project.

Create a new project.

Select the template Worker Service from all the available templates. You can search with relevant keywords from the top search bar.

Next, give project a name, in this example it is WorkerService1.

Next, select the target framework. (.Net Core 3.1 is selected in this example)

Define the service

Once the project is created, create a new class, say ProcessMessageService with this code:

    public class ProcessMessageService : BackgroundService
    {
        public ProcessMessageService()
        {

        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                //do actual work here...
                //we are writing log to text file every 5 seconds

                string folderPath = @"C:\Test\WorkerService\";
                string fileName = "ProcessMessageService-" + DateTime.Now.ToString("yyyyMMdd-HH") + ".txt";
                string filePath = System.IO.Path.Combine(folderPath, fileName);
                string content = DateTime.Now.ToString("yyyyMMdd-HH:mm:ss") + " - ProcessMessageService is running" + Environment.NewLine;

                System.IO.File.AppendAllText(filePath, content);

                await Task.Delay(5000, stoppingToken);
            }
        }
    }
	

ProcessMessageService class is inherited from BackgroundService abstract base class, which in turn implements the IHostedService interface, so ProcessMessageService class can override two functions:

  • public Task StartAsync(CancellationToken cancellationToken): will be called when the service is started.
  • public async Task StopAsync(CancellationToken cancellationToken): will be called when the service is shutdown/stopped.

But in this example, we have only override the BackgroundService's abstract method ExecuteAsync():

    protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
	
Whithin this method, we have defined the actual work for the service, in this exmaple it is writing to text log file by every 5 seconds. We have implemented the indefinite while loop which will keep checking for stoppingToken.IsCancellationRequested bool property as a termination condition.
	while (!stoppingToken.IsCancellationRequested)
	
One each iteration we are suspending the execution by 5 seconds using Task.Delay() method.
	await Task.Delay(5000, stoppingToken);
	

Install required dependencies

Make sure you have installed the following Nuget Packages for .Net Core 3.1, which are required to succefully build and publish the service and enable it to host in windows services.

  • Install-Package Microsoft.CodeAnalysis.Common -Version 3.11.0
  • Install-Package Microsoft.Extensions.Hosting -Version 3.1.17
  • Install-Package Microsoft.Extensions.Hosting.WindowsServices -Version 3.1.17

If you are using some later version of .Net Core, you may need to change the version of these Nuget Packages.

Register the IHostedService

In Program.cs file, you will find the function CreateHostBuilder() as:

public static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
	.ConfigureServices((hostContext, services) =>
	{
		services.AddHostedService<ProcessMessageService>();
	});
		

Make sure that in builder's ConfigureServices() method, you are adding your service through services.AddHostedService() function call.

Another important point is to call UseWindowsService() method from builder's object, otherwise you may get errors when you host this windows service and try to start it.

After making this change, the function will be like this:

public static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
	.UseWindowsService()
	.ConfigureServices((hostContext, services) =>
	{
		services.AddHostedService<ProcessMessageService>();
	});
		

References:

Related Post(s):

No comments:

Post a Comment