Background Tasks, Windows Services, and More with .NET Core Hosted Services

Scott Lusk
Hitachi Solutions Braintrust
6 min readMay 11, 2019

In this Article

Are you taking advantage of hosted services in ASP.NET Core yet? Did you know that you can run a Windows Service or Background Tasks using hosted services in .NET Core? If the answer is no to either of those questions, I hope this article leads you to some of the references I found very useful in regards to these very topics. I also hope it helps you dig deeper into your understanding of how this applies to you.

Overview

You’re in the right place if you are currently using or looking to use ASP.NET Core to create a self-contained Windows Service deployment or spin up some Background Tasks using hosted services. That’s not all you can do, of course, but that’s my experience and the focus I would like to take.

Something to note is that hosted services have been around since early .NET Core 2.0 was released and are similar to WebJobs as noted in this article. As with any situation, though, do your research and determine if an approach truly answers a business need you are trying solve before going all in.

This particular article focuses on topics covered in greater detail in the following Microsoft docs: Host ASP.NET Core in a Windows Service and Background tasks with hosted services in ASP.NET Core. If you follow the Microsoft docs you’ll end up with something similar to what I’ve shared in my example repository. The intent of this article is to highlight an approach that may be beneficial for a problem you are trying to solve.

Example Use Case

I’ve put together an example repository available here that demonstrates the combination of creating a Windows Service that can be hosted on Windows without using IIS following the examples given in Host ASP.NET Core in a Windows Service. The example also takes advantage of creating a timed background task that runs as outlined in Timed Background Task.

Specifically for my scenario, I needed to support executing a Windows Service on a machine still running Windows 7. Since .NET Core is currently supported for Windows 7 SP1, and there is an available RID for win7 as noted in the Windows RIDs, I figured this approach could pan out well for what we wanted to accomplish. I can confirm the end result was a success and I was able to install this machine running not only Windows 7 SP1 but also Windows 8 and Windows 10 as well.

Getting Started with the Sample Code

The article Host ASP.NET Core in a Windows Service focuses on converting an existing application over to a Windows Service. I took the approach of creating a brand new project and I’ll mention here some of the steps that I had to take.

In the example project I used .NET Core 2.2 and Visual Studio 2017. If you don’t already have the SDK download it at .NET Core 2.2 Downloads. You will want the SDK for your development environment if you don’t already have it but on any host machines where you will install the service you will need just the Runtime.

Create a New Project in Visual Studio. You will want to choose ASP.NET Core Web Application

Add New Project

Next choose the project template for the Web Application. I chose Web Application. Make sure your .NET Core version is set.

Web Application Project Template

At this point you can pick up in the Microsoft docs if you want to follow along — like I did — covering these sections:

Check out my initial commits to this repository to see how I followed along by browsing to repository at this point in history. At this point you have a Web Application just like any other and you can launch and test out the code using IIS Express in Visual Studio and see that you are running in Development mode.

It is important to note that when running in debug in Visual Studio your application is merely running as any other web application and is not yet taking advantage of the Hosted Service that was added to the project at this point. If you look at the page that is launched when the application starts you can see that the Environment.EnvironmentName indicates you are in running in Development mode.

If you were to put any break points in the CustomWebHostService.cs class you would not see those get hit. This is due to the code in line 21 below that was added in Program Main is not hit if the application is not running as a service as indicated on line 3.

Next Steps — Running as a Windows Service

The documentation referenced at Host ASP.NET Core in a Windows Service does a great job of making it pretty easy to set this up as a Windows Service. You will need PowerShell 6.2 to work through these that you can download here.

Specifically, focus on these portions of the article:

I personally ran into a problem with trying to Set permission for Log on as a service. Even after following the steps in the Microsoft doc, I had to open up services.msc, find my service, go to properties, and re-key the user’s password. At that point when I clicked on OK I was alerted that the user account would be granted Log on as a service right. I could not find a way around this at this time.

It’s also important to note that the RID you target when publishing the application is important and should match the runtime of the target machine where you plan to deploy your service. You will need to determine the deployment type you want to use. In my casse I chose to go with a Framework-dependent deployment (FDD), given that I knew the target machines would have .NET Core 2.2 already installed.

Adding Timed Background Tasks

If you’ve followed the Microsoft doc up to this point and the github repo I’ve referenced, by now you should be able to successfully run a hosted service on your machine. Now it’s time to start doing something with that service. In this scenario a monitor on a particular directory needed to be setup to watch for new files being placed in a folder by checking it for new files at certain intervals (i.e. every 60 seconds) and then uploading those files to Azure Storage.

You can take the code snippet found at Timed background tasks. It’s important to note that if you are going to use Dependency Injection with this service you should also follow the example shown at Consuming a scoped service in a background task to make this work with DI correctly. If you don’t set it up this way and you try to register anything other than transient dependencies you will likely see exceptions thrown.

The end result I ended up with looks something like the class below. Note the addition of IServiceProvider in the constructor and lines 38 thru 45 where the service provider is used to create the scope and get a reference to our IServiceWorker that is registered with Dependency Injection in the Startup.cs class.

Summary

I hope you found this article useful in getting a hosted serviced and a Timed background task setup quickly without any problems. I would love to know what your scenarios are where you are using a similar approach and always appreciate any feedback.

Resources

--

--