.NET Core 3.0新增了Worker Service的新项目模板,可以编写长时间运行的后台服务,并且能轻松的部署成windows服务或linux守护程序。如果安装的vs2019是中文版本,Worker Service的项目名称就变成了辅助角色服务。Worker Service 咱也不知道怎么翻译成了这个名称,咱也不敢乱翻译,下文就保持原名称。。。,本文将会演示如何创建一个Worker Service项目,并且部署为windows服务或linux守护程序运行;
开始创建worker service 项目
创建新项目——》选择 Worker Service(辅助角色服务)
取一个项目名称:DemoWorkerService
项目创建成功之后,您会看到创建了两个类:Program和Worker。
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace DemoWorkerService { 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>(); }); } }
Program类跟ASP.NET Core Web应用程序非常类似,不同之处没有了startup类,并且把worker服务添加到DI container中。
Worker.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace DemoWorkerService { 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); } } } }
worker只是一个简单的类,它继承自BackgroundService ,而后者又实现IHostedService接口。
注意上面worker类的构造函数中,使用了.NET Core自带的日志组件接口对象ILogger,它是通过DI(依赖注入)注入到worker类的构造函数中的,和ASP.NET Core中Controller的构造函数类似(关于ILogger,可以查看这里了解),我们也可以不用日志组件,给worker类定义无参的默认构造函数。
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; namespace DemoWorkerService { public class Worker : BackgroundService { public Worker() { } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await Task.Delay(1000, stoppingToken); } } } }
我们可以通过 override ExecuteAsync 方法来完成自己要做的事情,该方法实际上属于BackgroundService类,我们是在worker类中重写(override)了它,这个方法中我们就可以调用在windows服务或linux守护程序中要处理的逻辑,原则上来说这个逻辑应该是在一个死循环中,并且通过ExecuteAsync方法传入的参数对象CancellationToken,来判断是否应该结束循环,例如如果windows服务被停止,那么参数中CancellationToken类的IsCancellationRequested属性会返回false,那么我们应该停止ExecuteAsync方法中的循环,来结束整个windows服务:
//重写BackgroundService.ExecuteAsync方法,封装windows服务或linux守护程序中的处理逻辑 protected override async Task ExecuteAsync(CancellationToken stoppingToken) { //如果服务被停止,那么下面的IsCancellationRequested会返回false,我们就应该结束循环 while (!stoppingToken.IsCancellationRequested) { //模拟服务中的处理逻辑,这里我们仅输出一条日志,并且等待1秒钟时间 _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); await Task.Delay(1000, stoppingToken); } }
此外我们也可以在worker类中重写BackgroundService.StartAsync方法和BackgroundService.StopAsync方法,在开始和停止Worker Service服务(例如,开始和停止windows服务)的时候,来执行一些处理逻辑,本例中我们分别输出了一条日志:
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace DemoWorkerService { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } //重写BackgroundService.StartAsync方法,在开始服务的时候,执行一些处理逻辑,这里我们仅输出一条日志 public override async Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Worker starting at: {time}", DateTimeOffset.Now); await base.StartAsync(cancellationToken); } //重写BackgroundService.ExecuteAsync方法,封装windows服务或linux守护程序中的处理逻辑 protected override async Task ExecuteAsync(CancellationToken stoppingToken) { //如果服务被停止,那么下面的IsCancellationRequested会返回false,我们就应该结束循环 while (!stoppingToken.IsCancellationRequested) { //模拟服务中的处理逻辑,这里我们仅输出一条日志,并且等待1秒钟时间 _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); await Task.Delay(1000, stoppingToken); } } //重写BackgroundService.StopAsync方法,在结束服务的时候,执行一些处理逻辑,这里我们仅输出一条日志 public override async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Worker stopping at: {time}", DateTimeOffset.Now); await base.StopAsync(cancellationToken); } } }
由于BackgroundService类的StartAsync、ExecuteAsync、StopAsync方法返回的都是Task类型,所以如同上面代码所示,我们可以使用async和await关键字将它们重写为异步函数,提高程序的性能。
利用.NET Core中的Worker Service,来创建windows服务或linux守护程序(转载)
原文:https://www.cnblogs.com/OpenCoder/p/12191164.html