DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. Languages
  4. Worker Service Template in .NET Core 3.0

Worker Service Template in .NET Core 3.0

We take a look at a new addition to the .NET Core framework, the worker service template, and just how it works in our C# code.

Gunnar Peipman user avatar by
Gunnar Peipman
·
Mar. 12, 19 · Tutorial
Like (3)
Save
Tweet
Share
19.95K Views

Join the DZone community and get the full member experience.

Join For Free

With ASP.NET Core 3.0 Preview 3, we get a template for background processes like Windows services and Linux daemons. The new project template is called Worker Service and this post shows how it works and how to use it.

Creating a Worker Service Application

After downloading .NET Core 3.0 Preview 3, open Visual Studio 2019, create new ASP.NET Core web application, and select Worker service as the project type.

NB! Currently, Worker Service is located under ASP.NET Core web applications and the template uses the web SDK. This will change in the future as the intent of the development team is not to have any dependencies to other SDKs by default.

Default .NET Core Worker Service

With default implementation of the worker service, we get two classes: Program and Worker. The Program class is very straightforward and a little bit similar to what we have in web applications. The difference is that instead of a startup class we have a worker class and it is registered as a hosted service.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

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

To make things more interesting, compare the code here with the code shown in my post Running an ASP.NET Core Application as a Windows Service.

The Worker class is also very laconic. An interesting thing to notice is that it offers support for .NET Core dependency injection. Notice how the logger is given as a constructor argument of the Worker class. The worker class we get when creating new worker service project writes out current time after every second.

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: {DateTime.Now}");
            await Task.Delay(1000, stoppingToken);
        }
    }
}

Without any additional configuration changes, we can run the application to see it work.

Background Service Class

The Worker service class inherits from BackgroundService defined in Microsoft.Extensions.Hosting.Abstractions package. We can see that there are additional methods we can override: StartAsync(), StopAsync(), and Dispose(). StartAsync() and StopAsync() are inherited from the IHostedService interface.

public abstract class BackgroundService : IHostedService, IDisposable
{
    public virtual void Dispose();
    public virtual Task StartAsync(CancellationToken cancellationToken);
    public virtual Task StopAsync(CancellationToken cancellationToken);
    protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
}

We can use the StartAsync() method to initialize our worker service and StopAsync() to clean up when the worker is closing. If the worker made use of any disposable resources, then these resources must be disposed in the Dispose()  method that is the latest point for this.

Extending the Worker Service

As I had sample code already open in Visual Studio, I thought I'd see what happens when I override other methods of BackgroundService and write time to the log in the same way it was done with the ExecuteAsync() method.

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

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

    public override Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"Worker started at: {DateTime.Now}");

        return base.StartAsync(cancellationToken);
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation($"Worker running at: {DateTime.Now}");

        return Task.CompletedTask;
    }

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"Worker stopped at: {DateTime.Now}");

        return base.StopAsync(cancellationToken);
    }

    public override void Dispose()
    {
        _logger.LogInformation($"Worker disposed at: {DateTime.Now}");

        base.Dispose();
    }
}

And here is the result of running our extended worker service. Take a close look at the output.

We can see here all the worker service methods that were called. An interesting thing to notice is that  the worker service started before the application starts and it stopped after the application stopped. This is explained in the official document, Background tasks with hosted services in ASP.NET Core.

Project File

Just for interest, I also checked out what's inside the project file. Well, nothing special, I must say.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0-preview3.19153.1" />
  </ItemGroup>
</Project>

There's a reference to netcoreapp3.0 and the Microsoft.Extensions.Hosting NuGet package. So, no mysteries or surprises — everything is neat and clean.

Wrapping Up

The Worker service template is a good addition to .NET Core and it's good to see that the process hosting gets more and more generalized in .NET Core. At the same time, we still have some great features, like dependency injection, available. Perhaps the most interesting part is to see how the worker service will be used as a Windows service and Linux daemon and how much work it is to use.

Web Service .NET Template application ASP.NET Core

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Fargate vs. Lambda: The Battle of the Future
  • gRPC on the Client Side
  • [DZone Survey] Share Your Expertise and Take our 2023 Web, Mobile, and Low-Code Apps Survey
  • 10 Easy Steps To Start Using Git and GitHub

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: