Worker Service

Publish a .NET Core Worker Service to Azure

In last week’s post, .NET Core Worker Service, we created a .NET Core Worker Service and then showed how to host it as a Windows Service. This week we will be taking the application created in last week’s post and publishing it to Azure. If you haven’t read last week’s post I recommend you at least get through the application creation bits. Feel free to skip the part about making the application run as a Windows Service since we will be pushing to Azure for this post.

Publish to Azure

This post is going to assume you already have an active Azure account. If not you can sign up for a free Azure account. This post is also going to be using Visual Studio 2019 Preview for the publication process.

In Visual Studio right-click on the project and click Publish.

Since this project already has a folder publish setup from last week’s post my screenshot might look different from yours. Click the New link.

This will launch the Publish profile dialog. We will be publishing to Azure WebJobs using the Create New option. After verifying the settings are correct click Create Profile.

The next screen gets the details of the App Service that will be created. I did a new resource group instead of using the one that was defaulted in and a new hosting plan so that I could utilize the free tier, but both of these changes are optional. When you have everything set click the Create button.

Once create is clicked it takes a couple of minutes to deploy the application. This first deploy is going to be a throwaway for us. There are a few settings we need to tweak to get the application running the way we want. After the initial deployment is complete we end up back on the profile details screen. Click the Edit link.

The Publish Profile Settings dialog will show. Since this was written while .NET Core 3 is still in preview I’m using the Self-contained option for Deployment Mode. If you are doing this after the final release then you can skip this step. The second thing I am changing is the WebJob Type and I’m setting it to Continuous. This is because our Service is controlling its own work schedule and not being triggered by something else. Click Save to commit the changes and return to the publish dialog.

Now push the Publish button to push the application to Azure.

Use Azure Portal to Verify Application is Working

Now that our application is running in Azure how do we verify that it is actually executing as we expect? Since the only thing the sample application does it output some logs we are going to have to find a way to show the output of the logging. To start head over to the Azure Portal. Since we just published the application the resource we are interested in should show in your Recent resources section of the Azure Portal homepage. As you can see in the screenshot the one we are interested in is the first option and matches the name we saw above in Visual Studio. Click on the resource.

From the menu section scroll down to the Monitoring section and click App Service logs. Now turn On the option for Application Logging (Filesystem) and for the Level option select Information since that is the log level our sample application is outputting. Then click Save.

Back in the same Monitoring group of the menu select Log stream.

Wrapping Up

Running a worker in Azure ended up being pretty simple. Not that I’m surprised Microsoft tends to make all their products work well with Azure. I’m sure you will find a way to make a more useful worker than we had in this example.

.NET Core Worker Service

A year or so ago I wrote the post Host ASP.NET Core Application as a Windows Service. With the upcoming release of .NET Core 3, we now have another option for creating a service with the new Worker Service template. This post is going to walk through creating a new application using the new Worker Service template and then running the service as a Windows Service.

Project Creation

I’m going to use Visual Studio 2019 Preview for this process. If you would rather you can use the .NET CLI with the following command to create the project instead.

dotnet new worker

For the Visual Studio, open the application and select the Create a new project option.

On the next screen search for Worker Service and click Next.

On the next screen enter a Project name and click the Create button.

Next, click the create button to finally create the project, unless you want to use Docker.

Project Structure

The resulting structure is pretty simple. The two files that we will be dealing with are Program.cs and Worker.cs.

Program.cs is the entry point for the application and defines the different works you want to run. The following is an example that sets up two different workers. The default template only has one worker, but I added the second one to show multiple workers are an option.

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

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

Worker.cs contains the code that gets called to execute work. The following is the default worker that gets created from the template. This worker just writes a log once a 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: {time}",
                                   DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }
}

At this point, you could run the application and it would do whatever work you have it set up to perform.

Run as a Windows Service

To run the project as a Windows Service we need to add a NuGet package. To do this right-click on the project file and select Manage NuGet Packages.

In the NuGet dialog click the Browse tab, check the Include prerelease checkbox, search for Microsoft.Extensions.Hosting.WindowsServices, and finally click Install.

After the package is installed open Program.cs and add a call to UseWindowsService to host builder in the CreateHostBuilder function.

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

Publish the Application

Now that we have the application set up to be able to run as a Windows service we need to publish it. To publish from the .NET CLI you can use the following command in the directory with the solution or project file. There is also an option for an output location if you want it to go to a different directory.

dotnet publish

Or from Visual Studio click the Build > Publish {Solution Name} menu. Select the Folder option on the left and then click Create Profile.

On the next screen click the Publish button.

Service Installation and Management

At this point, the application can be installed and managed like any other Windows service. To install the service open a command prompt in admin mode and run the following command to create a windows service. The binPath needs to be the full path to your exe or your service will fail to start even it is created successfully.

sc create WindowsServiceHosted binPath= "C:\Users\eanderson\Desktop\Worker\Worker\bin\Debug\netcoreapp3.0\publish\Worker.exe"

Also, note that the space after binPath= and before the exe name is needed.

Now that the service is installed run the following command to start it.

sc start Worker

To check the state of your service use the following command.

sc query Worker

To stop your service use the following command.

sc stop Worker

Finally, to uninstall your service use the following command.

sc delete Worker

Wrapping Up

This template makes it really easy to get started with a worker. Hopefully, this will help you get started. Make sure and check out the .NET Core Workers as Windows Services post from Microsoft.