Introduction
In this tutorial you’ll set up and deploy a production-ready ASP.NET Core application on Windows or Ubuntu 18.04 using worker service .
os:windows server 2012 R2
.net core:net core 3.1.1
or
.net core:net core 5.x
1. Create a worker service application
step 1:Creating a Default .NET Core worker service application
Create a Worker on the command line:
dotnet new worker -o Stockso.WindowsService
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>();
});
}
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);
}
}
}
step 2: Extending worker service
Worker service class inherits from BackgroundService defined in Microsoft.Extensions.Hosting.Abstractions package,We can override: StartAsync(), StopAsync() and Dispose(). StartAsync() and StopAsync() are inherited from 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);
}
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Stockso.WindowsService
{
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);
}
}
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"{DateTime.Now}: Worker started.");
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"{DateTime.Now}:Worker stopped. ");
return base.StopAsync(cancellationToken);
}
public override void Dispose()
{
_logger.LogInformation($"{DateTime.Now}:Worker disposed.");
base.Dispose();
}
}
}
step 3:Test the Application Directly at a command prompt
Run the app at a command prompt
output:
cd G:\xx\WorkerService
dotnet run
info: Stockso.WindowsService.Worker[0]
2020/6/20 3:58:26: OutIpService.WorkerService Worker started.
info: OutIpService.WorkerService.Worker[0]
Worker running at: 06/20/2020 03:58:26 +08:00
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: G:\xxx\src\OutIpService\OutIpService.WorkerService
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
info: OutIpService.WorkerService.Worker[0]
2020/6/20 3:58:30:OutIpService.WorkerService Worker stopped.
info: OutIpService.WorkerService.Worker[0]
2020/6/20 3:58:30:OutIpService.WorkerService Worker disposed.
step 4:publish
dotnet publish -o C:\path\to\project\pubfolder
or
cd F:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WorkerService\
dotnet publish -c release
you can get
G:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WindowsService\bin\release\net5.0\publish\Stockso.WindowsService.dll
and
G:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WindowsService\bin\release\net5.0\publish\Stockso.WindowsService.exe
2.Run .NET Core Worker Service as a Windows Service
Install the Worker service on windows 2012 R2(Run as a Windows Service)
Install the Worker as Windows Services
step 1.preprare Windows service
In order to run as a Windows Service we need our worker to listen for start and stop signals from ServiceBase the .NET type that exposes the Windows Service systems to .NET applications.
To do this we want to:
Add the Microsoft.Extensions.Hosting.WindowsServices NuGet package
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
</Project>
Add the UseWindowsService call to the HostBuilder in our Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
first,publish the Worker Service as an exe file with dependencies.
run the following dotnet command:
dotnet publish -o C:\path\to\project\pubfolder
step 2.create Windows Services
second,Run the sc utility (from Windows\System32) to create a new service.
you must run cmd as administrators Windows PowerShell then you can create Windows Services .Then we can use the sc utility in an admin command prompt:
C:\Windows\System32\sc create Stockso.WindowsService binPath=F:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WindowsService\bin\release\net5.0\publish\Stockso.WindowsService.exe
output
PS C:\Windows\system32> C:\Windows\System32\sc create Stockso.WindowsService binPath=F:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WindowsService\bin\release\net5.0\publish\Stockso.WindowsService.exe
[SC] CreateService 成功
otherwise,you can get error:
[SC] OpenSCManager 失败 5:拒绝访问
step 3.Start Windows Services
Three, start Stockso.WindowsService
sc start Stockso.WindowsService
other:Create and manage the Windows Service
sc.exe create Stockso.WindowsService DisplayName= "Stockso.WindowsService" binpath= "C:\Program Files\dotnet\dotnet.exe G:\stock\ReadDZHRealTime\src\WinTimerTask\Stockso.WindowsService\bin\release\netcoreapp3.1\publish\Stockso.WindowsService.dll --run-as-service"
sc start Stockso.WindowsService
sc stop Stockso.WindowsService
sc delete Stockso.WindowsService
sc config Stockso.WindowsService start=AUTO
sc config Stockso.WindowsService start= DEMAND
sc config Stockso.WindowsService start= DISABLED
net start Stockso.WindowsService
net stop Stockso.WindowsService
System and Application Event Logs
Default the EventLogLoggerProvider to warning or above.you must use:
_logger.LogWarning($"some information");
error
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"{DateTime.Now}: {applicationName} Worker started.");
return base.StartAsync(cancellationToken);
}
correct
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogWarning($"{DateTime.Now}: {applicationName} Worker started.");
return base.StartAsync(cancellationToken);
}
Access the System and Application Event Logs:
Open the Start menu, search for Event Viewer, and select the Event Viewer app.
In Event Viewer, open the Windows Logs node.
Select System to open the System Event Log. Select Application to open the Application Event Log.
Search for errors associated with the failing app.
3.Install the Worker service on Linux
preprare Linux service
Add the Microsoft.Extensions.Hosting.Systemd NuGet package
Add the UseSystemd() call to the HostBuilder in our Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
resource
1.Host ASP.NET Core 3.x in a Windows Service
2.Worker Service sample
3.CreateDefaultBuilder(string[] args)
4.worker-scope/Worker.cs