利用.NET Core中的Worker Service,来创建windows服务或linux守护程序(转载)

.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

扫描二维码关注公众号,回复: 8590463 查看本文章
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);
        }
    }
}

待续

猜你喜欢

转载自www.cnblogs.com/OpenCoder/p/12191164.html
今日推荐