August 16, 2021

.NET Core Worker Service - Implementing by IHostedService

In ASP.NET Core, background tasks can be implemented as hosted services.

ASP.NET Core 3 offers a new feature to implement Windows Service, i.e. Worker Service.

Worker Service is an ASP.NET Core project template that allows you to create long-running background services. The interesting point is that dependency injection is available natively with Worker Service project template.

You can implement Worker Service class by two ways:

  • Implement the IHostedService interface
  • Derive from BackgroundService abstract base class

In this post we will see an example how to define Worker Service by implementing the IHostedService interface.

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 : IHostedService
    {
        public Task StartAsync(CancellationToken cancellationToken)
        {
            DoWork(cancellationToken).GetAwaiter().GetResult();
            
            return Task.CompletedTask;
        }

        private async Task DoWork(CancellationToken cancellationToken)
        {
	//check if service is not canceled
            while (!cancellationToken.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, cancellationToken);
            }
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await Task.Delay(-1, cancellationToken);

            cancellationToken.ThrowIfCancellationRequested();
        }
    }
	

ProcessMessageService class has implemented the interface IHostedService, so it have to define 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.

Inside StartAsync() method, we have called our custom method DoWork() which will actually do the job we want this service to do. In this exmaple it is writing to text log file by every 5 seconds.

Install required dependencies

Make sure you have installed the following Nuget Packages for .Net Core 3.1.

  • 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>();
	});
		

The coding part is done, next step is to publish the Worker Service to an exe file, which will be covered in next post.

References:

Related Post(s):

No comments:

Post a Comment