天天看點

.NET Core 3.1和WorkerServices建構Windows服務

介紹

ASP.NET Core 3增加了一個非常有意思的功能Worker Service.他是一個ASP.NET Core模闆,他允許我們建立托管長期的運作的背景服務,這些服務具體實作IHostedService接口的背景任務邏輯,他被成為"托管服務".同時他們可以部署到windows中Windows服務,以及Linux守護程式.

建立一個托管服務

我們通過指令行界面中的dotnet new 指令。通過如下代碼建立一個名為customWorker的WorkerService的應用。

dotnet new worker -o customWorker
           

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceDemo
{
    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>();
                });
    }
}

           

Worker:

BackgroundService是實作了IHostedService的基類.調用 ExecuteAsync(CancellationToken) 來運作背景服務。實作傳回一個Task,其表示背景服務整個生存期.在 ExeuteAsync(例如通過調用await)之前,不會啟動任何其他服務.避免在ExecuteAsync中執行長時間的阻塞初始化. StopAsync(CancellationToekn) 中的主機塊等待完成ExecuteAsync。

調用 IHostedService.StopAsync 時,将觸發取消令牌。 當激發取消令牌以便正常關閉服務時,ExecuteAsync 的實作應立即完成。 否則,服務将在關閉逾時後不正常關閉。

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 WorkerServiceDemo
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

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

        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            await base.StartAsync(cancellationToken);
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            await base.StopAsync(cancellationToken);
        }

        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 void Dispose()
        {
        }
    }
}
           

已使用AddHostedService擴充方法在 IHostBuilder.ConfigureServices(Program.cs)中注冊該服務。

services.AddHostedService<Worker>();
            

WorkerServices部署到Windows服務

安裝 WorkerServices模闆

.NET Core 3.1和WorkerServices建構Windows服務

在IHostBuilder使用UseWindowsService擴充方法

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;


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

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

        }
    }
}

           

現在我們可以部署我們的windows服務了。

釋出方式

  • 使用sc.exe工具
  • 直接部署exe檔案

釋出Windows服務

dotnet restore
dotnet publish
           

sc.exe部署

sc.exe create DemoWorker binpath= publish\xxxx.exe
sc.exe start WorkerServicesName
           

部署exe檔案

WorkerServicesName.exe install
WorkerServicesName.exe start
           

使用sc.exe停止和删除

sc.exe stop WorkerServicesName 
sc.exe delete WorkerServicesName 
           

非sc.exe停止和删除

WorkerServicesName stop  
WorkerServicesName uninstall
           

在Linux設定守護程式

添加Microsoft.Extensions.Hosting.Systemd NuGet軟體包

.NET Core 3.1和WorkerServices建構Windows服務

将UseSystemd()添加上。

public static IHostBuilder CreateHostBuilder(string[] args)
        {

            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                }).UseSystemd();

        }
           

在Linux上設定為守護程式。

Reference

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-3.1&tabs=visual-studio https://github.com/hueifeng/BlogSample/tree/master/src/WorkerServiceDemo

繼續閱讀