Building a Windows service with Worker Services and .NET Core 3.1, part 2: Migrate a timed service built with TopShelf


Before Worker Services in ASP.NET Core 3, there was a famous and practical way to implement a Windows service: TopShelf. This library provides a way to create a Windows service from a Console Application.

I wrote an article three years ago about TopShelf and Ninject ( and in this article we will review that implementation and migrate it to ASP.NET Core 3 Worker Service.

Implementation of a timed service with TopShelf and Ninject

I used to build my Windows service with Ninject and TopShelf. Ninject is an open source dependency injection container for .NET and .NET Core.

Because dependency injection is native with .NET Core, I will no longer use any container except the default one provided by the framework.

Let’s consider the following service to be injected:

Dependency injection registration with Ninject:

Windows Service configuration with TopShelf:

Example of a timed service built with TopShelf:

I used Wait method because I don’t need asynchronous execution in that context. I’am running each iteration of a service since the previous is done.

Migrate to a timed Worker service

Let’s migrate! We won’t use a BackgroundService, we will build a class that implements IHostedService and IDisposable. We don’t need ExecuteAsync method.

Because Timer class has evolded since 2016, its implementation will change compared to the version I showed above. I only need to implement StartAsync, StopAsync and Dispose because IDisposable.

Because I no longer use Ninject nor TopShelf, the Service worker implementation and configuration are simpler:

Services registration take only on line:

And the implementation is quite easy too:

One again, because processing is sequential no need to use asynchronous tasks, then we don’t need to manage non blocking operations.

If you run the service, you’ll the the sequence works fine with Monitor, no operation will be fired while the current operation hasn’t ended.



This article showed you how to build a long time running (finally infinite) task without necessarily implementing a background service with BackgroundService. If you were using TopShelf it’s time to migrate! 🙂

Written by


Anthony is a specialist in Web technologies (14 years of experience), in particular Microsoft .NET and learns the Cloud Azure platform. He has received twice the Microsoft MVP award and he is also certified Microsoft MCSD and Azure Fundamentals.
%d bloggers like this: