.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模板
在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软件包
将usesystemd()添加上。
public static ihostbuilder createhostbuilder(string[] args) { return host.createdefaultbuilder(args) .configureservices((hostcontext, services) => { services.addhostedservice<worker>(); }).usesystemd(); }
在linux上设置为守护程序。
reference
https://github.com/hueifeng/blogsample/tree/master/src/workerservicedemo