Scott Hanselman

dotnet new worker - Windows Services or Linux systemd services in .NET Core

August 23, '19 Comments [9] Posted in DotNetCore | Open Source
Sponsored By

dotnet new workerYou've long been able to write Windows Services in .NET and .NET Core, and you could certainly write a vanilla Console App and cobble something together for a long running headless service as well. However, the idea of a Worker Process, especially a long running one is a core part of any operating system - Windows, Linux, or Mac.

Now that open source .NET Core is cross-platform, it's more than reasonable to want to write OS services in .NET Core. You might write a Windows Service with .NET Core or a systemd process for Linux with it as well.

Go grab a copy of .NET Core 3.0 - as of the time of this writing it's very close to release, and Preview 8 is supported in Production.

If you're making a Windows Service, you can use the Microsoft.Extensions.Hosting.WindowsService package and tell your new Worker that its lifetime is based on ServiceBase.

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

If you're making a Linux worker and using systemd you'd add the Microsoft.Extensions.Hosting.Systemd package and tell your new Worker that its lifetime is managed by systemd!

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

The Worker template in .NET Core makes all this super easy and familiar if you're used to using .NET already. For example, logging is built in and regular .NET log levels like LogLevel.Debug or LogLevel.Critical are automatically mapped to systemd levels like Debug and Crit so I could run something like sudo journalctl -p 3 -u testapp and see my app's logs, just alike any other Linux process because it is!

You'll notice that a Worker doesn't look like a Console App. It has a Main but your work is done in a Worker class. A hosted service or services is added with AddHostedService and then a lot of work is abstracted away from you. The Worker template and BackgroundService base class brings a lot of the useful conveniences you're used to from ASP.NET over to your Worker Service. You get dependency injection, logging, process lifetime management as seen above, etc, for free!

public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;

public Worker(ILogger<Worker> logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}

This is a very useful template and it's available from the command line as "dotnet new worker" or from File New Project in Visual Studio 2019 Preview channel.

Also check out Brady Gaster's excellent blog post on running .NET Core workers in containers in Azure Container Instances (ACI). This is super useful if you have some .NET Core and you want to Do A Thing in the cloud but you also want per-second billing for your container.


Sponsor: Get the latest JetBrains Rider with WinForms designer, Edit & Continue, and an IL (Intermediate Language) viewer. Preliminary C# 8.0 support, rename refactoring for F#-defined symbols across your entire solution, and Custom Themes are all included.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Wednesday, August 28, 2019 6:24:03 AM UTC
Hi Scott, thanks for the post! How about a service running on macOS? Is there any specific package available?
Maarten
Wednesday, August 28, 2019 6:47:09 AM UTC
Hi! Have you heard of TopShelf? Is it obsolete for .NET Core now, because of this new worker concept?
D.R.
Wednesday, August 28, 2019 10:16:06 AM UTC
How does this apply to netcore console apps running in Linux Containers? Should SystemD still be used?
Maciek Misztal
Wednesday, August 28, 2019 1:42:17 PM UTC
Thank you so much, Scott! It's very valuable on "dotnet new worker". For users of .NET framework, it's very useful article to know about new services. Just a small question, what do you think for which is it beneficial more- Windows or Linux?? Thanks again and keep sharing!!
Wednesday, August 28, 2019 3:23:40 PM UTC
Maciek: If running in a Linux container, you should continue to use a normal console application and define that app as your entrypoint. Systemd, like windows services, run in the OS background. If for no other reason, you'd need something else in your entrypoint just to monitor the systemd and keep running. Otherwise the Docker container would exit.
Richard Gavel
Wednesday, August 28, 2019 6:27:28 PM UTC
Hi Scott.
There are some ways to create a Hosted Service without thinking about the OS production environment? What happens if I have two environments with differents OS?
Best
Leandro Witzke
Saturday, August 31, 2019 6:20:55 AM UTC
Leandro,


.UseWindowsService()
.UseSystemd()

could be used together. When on Linux host, the UseWindowsService() call will be ignored, and vice versa for the UseSystemd() call when on a Windows host.
Henrik Larsson
Tuesday, September 03, 2019 5:02:46 AM UTC
Thanks, Scott Love to read .Net Core info Provided by you.
Wednesday, September 04, 2019 3:19:56 PM UTC
What is the best Game Hosting Control Panel in terms of security, I heard GSPanel is pretty good.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.