使用.NET Core创建Windows服务 - 使用.NET Core工作器方式

原文:Creating Windows Services In .NET Core – Part 3 – The “.NET Core Worker” Way

作者:Dotnet Core Tutorials

译者:Lamond Lu

译文:使用.NET Core创建Windows服务 - 使用.NET Core工作器方式

使用.NET Core创建Windows服务

  • 使用微软推荐方式

  • 使用Topshelf方式


安装步骤

这里首先你要确保你已经安装了.NET Core 3.0或以上版本。在我编写这篇文章的时候, .NET Core 3.1刚刚发布,Visual Studio应该会提示你升级到最新版本。但是如果你想要在.NET Core 2.x项目中使用这个方式,应该是行不通的。

如果你喜欢使用命令行创建项目,你就需要使用工作器(worker)类型创建项目:

dotnet new worker

如果你是一个和我一样喜欢使用Visual Studio的开发人员,那么你可以在Visual Studio中使用项目模板完成相同的功能。

这样做将创建出一个包含两个文件的项目。其中Program.cs文件是应用的启动“引导程序”。另外一个文件是worker.cs文件,在这个文件中,你可以编写你的服务逻辑。

这看起来应该是相当的容易,但是为这个程序添加额外的并行后台服务,你还需要添加一个类,并让它继承BackgroundService类:

public class MyNewBackgroundWorker : BackgroundService
{protected override Task ExecuteAsync(CancellationToken stoppingToken)    {//Do something.}}

然后在Program.cs中,我们要做的只是把当前的Worker注册到服务集合(Service Collection)中即可。

.ConfigureServices((hostContext, services) =>
{services.AddHostedService<Worker>();services.AddHostedService<MyNewBackgroundWorker>();
});

实际上作为“后台服务”任务的运行程序,AddHostedService方法已经在框架中存在了很长时间了。在之前我们已经完成的一篇关于ASP.NET Core托管服务的文章, 但是在当时场景中,我们托管是是整个应用,而非一个在你应用程序幕后运行的东西。

运行/调试我们的应用

在默认的工作器(worker)模板中,已经包含了一个后台服务,这个服务可以将当前时间输出到控制台窗口。下面让我们点击F5来运行程序,看看我们能得到什么。

info: CoreWorkerService.Worker[0]Worker running at: 12/07/2019 08:20:30 +13:00
info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.

在我们启动程序之后,程序立刻就运行了!我们可以保持控制台的打开状态来调试应用,或者直接关闭窗口退出。相较于使用"Microsoft"方式来调试一个Windows服务,这简直就是天堂。

这里我们需要注意的另外一件事情是编写控制台程序的平台。在最后,我们不仅在控制台窗口输出了时间,还通过依赖注入创建了一个托管worker. 我们也可以使用依赖注入容器来注入仓储,配置环境变量,获取配置等。

但这里我们还没有做的事情是,将这个应用转换为Windows服务。。

将我们的应用转换成Window服务

为了将应用转换成Windows服务,我们需要使用如下命令引入一个包。

Install-Package Microsoft.Extensions.Hosting.WindowsServices

下一步,我们需要修改Program.cs文件,添加UseWindowsService()方法的调用。

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

以上就是所有需要变更的代码。

运行我们的程序,你会发现和之前的效果完全样。但是这里最大的区别是,我们可以将当前应用以Windows服务的形式安装了。

为了实现这一目的,我们需要发布当前项目。在当前项目目录中,我们可以运行以下命令:

dotnet publish -r win-x64 -c Release

然后我们就可以借助标准的Windows服务安装器来安装当前服务了。

sc create TestService BinPath=C:\full\path\to\publish\dir\WindowsServiceExample.exe

当前,你也可以使用Windows服务安装器的其他命令。

sc start TestServicesc stop TestServicesc delete TestService

最后检查一下我们的服务面板。

服务已经正常工作了。

在Linux中运行服务

老实说,我没有太多的Linux经验,但是终归是需要了解一下...

在Linux系统中, 如果你希望我们编写的“Windows”服务在Linux系统中作为服务运行,你需要做以下2步:

  • 使用Microsoft.Extensions.Hosting.Systemd替换之前的Microsoft.Extensions.Hosting.WindowsServices

  • 使用UseSystemd()替换UseWindowsService()

Microsoft vs Topshelf vs .NET Core Workers

到现在为止,我们已经介绍了借助3种不同的方式来创建Windows服务。

你可能会问“好吧,那我到底应该选择哪一种?”

这里呢,我们可以首先把"Microsoft"这种老派学院式的方式抛弃。因为它的调试实在是太麻烦了,而且没有什么实际的用处。

然后剩下的就是Topshelf和.NET Core工作器两种方式了。在我看来,.NET Core工作器,已经很好的融入.NET Core生态系统,如果你正在开发ASP.NET Core应用,那么使用.NET Core工作器就很有意义。最重要的是,当你创建一个后台服务的时候,你可以让它在一个ASP.NET Core网站中的任意位置运行,这非常的方便。但是缺点是安装。你必须使用SC命令来安装服务。这一部分Topshelf可能更胜一筹。

Topshelf总体上将非常的友好,并且具有最好的安装方式,但是使用额外的库,也增加了学习的成本。

所以Topshelf和.NET Core工作器,大家可以自行选择,都是不错的方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode贪心 最长回文串

Given a string s which consists of lowercase or uppercase letters, return the length of the longest palindrome that can be built with those letters. Letters are case sensitive, for example, “Aa” is not considered a palindrome here. 思路 首先学习一个新单…

【译】Visual Studio 2019 中 WPF UWP 的 XAML 开发工具新特性

原文 | Dmitry翻译 | 郑子铭自Visual Studio 2019推出以来&#xff0c;我们为使用WPF或UWP桌面应用程序的XAML开发人员发布了许多新功能。在本周的 Visual Studio 2019 版本 16.4 和 16.5 Preview 1中&#xff0c;我们希望借此机会回顾一下全年的新变化。如果您错过了我们以前的…

numpy创建zeros数组时报错TypeError: Cannot interpret ‘8‘ as a data type

错误代码 xPoint np.zeros(pow(2, k), pow(2, k))改正方法 zeros括号内填数组行列数时&#xff0c;加一对括号。 正确代码 xPoint np.zeros((pow(2, k), pow(2, k)))

我在外包公司做增删改查有前途么?

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;起因这是我无意中在筛选简历时&#xff0c;看到一位朋友发布的求职说明中&#xff0c;明确指出&#xff0c;外包勿扰&#xff0c;并给出了他做出这个决定的理由&#xff1a;…

csv.reader读取txt中的文本数据

Python里读取txt文件的方法有很多&#xff0c;但numpy读取字符串比较困难&#xff0c;这时可以考虑使用csv库&#xff0c;读取txt文件中的每一行文本。 代码 data [] with open(*******.txt, rt) as csvfile:reader csv.reader(csvfile, delimiter,)for row in reader:data…

[译]C#8.0中一个使接口更加灵活的新特性-默认接口实现

9月份的时候&#xff0c;微软宣布正式发布C#8.0&#xff0c;作为.NET Core 3.0发行版的一部分。C#8.0的新特性之一就是默认接口实现。在本文中&#xff0c;我们将一起来聊聊默认接口实现。众所周知&#xff0c;对现有应用程序的接口进行更改是一项很危险的操作。如果这个接口又…

Linux服务器 常用命令

定义当前文件夹中有result.txt 查看当前文件夹ls 查看当前路径pwd 进入目录homecd home 返回上一级目标cd .. 查看文件内容less result.txt 删除文件rm result.txt 查看进程信息top

鲲鹏来了,在EulerOS试用.NETCore-3.1

在EulerOS试用.NETCore-3.1前言EulerOS其实出来有一段时间了&#xff0c;一直在关注&#xff0c;单是仅仅也只是停留在观望的阶段&#xff0c;目前还没有接入的打算&#xff1b;正好看到园子里的兄弟分享了华为云免费试用的活动后&#xff0c;难捺激动的心情&#xff0c;我马上…

scp连接计算节点操作

定义计算节点为ip&#xff0c;计算节点用户名为name&#xff0c;待运行的文件名为file&#xff0c;其在登录节点的路径为path&#xff0c;登录节点文件夹名为log 登录计算节点 ssh nameip将登录节点的文件传输到计算节点 scp -r file nameip:path反之&#xff0c;将计算节点…

如何在ASP.NET Core 中快速构建PDF文档

比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发&#xff0c;随着这并不难&#xff0c;但还是会手忙脚乱的去搜索一些资料&#xff0c;那么恭喜您&#xff0c;这篇帖子会帮助到您&#xff0c;我们就不会再去浪费一些宝贵的时间。在本文中我们将要使用DinkToPD…

动态规划 0-1背包问题 二维数组

定义 dp[i][j]是从物品0到i中挑选物品&#xff0c;放进容量为j的背包中的最大价值总和。 初始化 int dp[maxn][maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f);for(int j bag_size; j > 0; j--) dp[0][j] dp[0][j-weight[0]] values[0];先遍历物品法 for(int i 0; i &l…

在VS2019发布独立程序与单一执行程序

背景随着.NET Core 3.1 LTS的发布&#xff0c;.NET Core 3.1 进入了3年的支持周期&#xff0c;在这期间使用.NET 的人数肯定会发生一个质的飞跃。01目标本次主要集中在使用.NET Core 3.1 WPF程序发布一个独立的单一执行程序。首先&#xff0c;新建一个wpf项目&#xff0c;名称为…

动态规划 0-1背包问题 滚动数组

定义 dp[j]是从物品0到i中挑选物品&#xff0c;放进容量为j的背包中的最大价值总和。 初始化 int dp[maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f);一维滚动数组法 for(int i 0; i < weight.size(); i)for(int j bag_size; j > 0; j--){if(j < weight[i])dp[j] …

C#异步编程看这篇就够了

随着.NET Core的流行&#xff0c;相信你现在的代码中或多或少的会用到async以及await吧&#xff01;毕竟已成标配。那么我们为什么要用async以及await呢&#xff1f;其实这是微软团队为我们提供的一个语法糖&#xff0c;让我们不用996就可以轻松的编写异步代码&#xff0c;并无…

sklearn PCA特征降维

机器学习中降维能够消除冗余&#xff0c;防止过拟合&#xff1b;发现潜在特征&#xff1b;减小计算量&#xff0c;节省资源和时间&#xff0c;常用的降维方法有&#xff1a;PCA &#xff0c;ICA&#xff0c;SOM&#xff0c;MDS&#xff0c; ISOMAP&#xff0c;LLE&#xff0c;本…

2019 AI Bootcamp·Guangzhou 参会日记

2019年的全球AI训练营在北京、上海、广州、杭州、宁波五个地方同时举办&#xff01;12月14日&#xff0c;微软全球AI Bootcamp活动再次驾临广州&#xff0c;本次会议结合 ML.NET 和基于 SciSharp 社区介绍最新的基于 .NET Core 人工智能技术&#xff0c;还有云端人工智能解决方…

LeetCode动态规划 杨辉三角

Given an integer numRows, return the first numRows of Pascal’s triangle. In Pascal’s triangle, each number is the sum of the two numbers directly above it as shown: 前几天做的动态规划题好难呜呜&#xff0c;做道水题找回自信~ 状态转移方程 triangle[i][j] …

AI Boot Camp 分享之 ML.NET 机器学习指南

今天在中国七城联动&#xff0c;全球134场的AI BootCamp胜利落幕&#xff0c;广州由卢建晖老师组织&#xff0c;我参与分享了一个主题《ML.NET 机器学习指南和Azure Kinect .NET SDK概要》&#xff0c;活动虽然只有短短的2天时间的宣传&#xff0c;报名70人&#xff0c;到场40多…

LeetCode动态规划 分割等和子集

Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. 思路 这道题假如能看出是一道0-1背包问题的话&#xff0c;就很好解决了。题目说需要划分…

使用 Ocelot 匹配路由的方法匹配路由

使用 Ocelot 匹配路由的方法匹配路由Intro之前我们在 Ocelot 网关的基础上自定义了一个认证授权的 Ocelot 中间件&#xff0c;根据请求的路径和 Method 进行匹配&#xff0c;找到对应的权限配置&#xff0c;并判断是否可以拥有访问资源的角色&#xff0c;如果没有则返回 401/40…