使用 .NET 6 构建跨平台 Worker Service 服务:跨越平台的 C# 服务开发——解决Windows服务跨平台问题
现代软件开发中,构建跨平台的应用程序变得愈加重要。C# 和 .NET 6 的出现使得在 Windows、Linux 和 macOS 上创建背景服务变得简单而高效。在本指南中,我们将通过创建一个使用 .NET 6 的 Worker Service 来展示如何实现跨平台后台服务。
项目概述
我们将创建一个简单的后台服务,该服务每隔一秒记录当前时间到日志中。此示例将使用 Visual Studio 2022 的 Worker Service 模板来实现,并演示如何在不同的平台上运行和部署。
1. 创建跨平台 Worker Service
1.1 安装 Visual Studio 2022
确保您已经安装了 Visual Studio 2022,并且在安装过程中选择了 ".NET 6.0" 工作负载。
1.2 创建 Worker Service 项目
- 启动 Visual Studio 2022。
- 点击 "创建新项目"。
- 在搜索框中输入 "Worker"。
- 选择 "Worker Service" 模板,点击 "下一步"。
- 输入项目名称(例如
MyCrossPlatformService),选择位置并点击 "创建"。
此时,Visual Studio 将生成一个基本的 Worker Service 项目结构。
2. 项目结构
创建的项目结构如下:
MyCrossPlatformService/
├── MyCrossPlatformService.csproj
├── Program.cs
└── Worker.cs
3. 实现 Worker Service服务
3.1 编辑 Worker.cs
打开 Worker.cs 文件,修改代码以实现每隔一秒记录当前时间的逻辑:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;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); // 每秒执行一次}}
}
4. 配置主程序
4.1 编辑 Program.cs
在 Program.cs 中配置和启动应用:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;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>();});
}
5. 运行服务
5.1 在 Windows 上运行
在 Visual Studio 2022 中,可以直接使用调试工具运行服务:
- 点击菜单中的 "调试" > "开始调试"(或按 F5)。
- 控制台窗口将打开,并每秒记录当前时间。
5.2 在 Linux 上运行
要在 Linux 上运行此服务,您需要发布它并使用命令行运行。可以使用以下步骤:
- 在 Visual Studio 中右键单击项目,选择 “发布”。
- 选择目标(例如文件夹),设置输出路径,并选择发布配置(Release)。
- 点击 “发布”。
发布完成后,您可以将输出文件夹中的内容部署到 Linux 系统上,然后使用以下命令运行:
dotnet MyCrossPlatformService.dll
6. 部署为系统服务
在 Linux 上,可以将该应用注册为 systemd 服务以便于管理。
6.1 创建 systemd 服务文件
创建一个 systemd 服务文件,文件名为 /etc/systemd/system/mycrossplatformservice.service,内容如下:
[Unit]
Description=My Cross-Platform Service[Service]
WorkingDirectory=/path/to/your/publish
ExecStart=/usr/bin/dotnet /path/to/your/publish/MyCrossPlatformService.dll
Restart=always
SyslogIdentifier=mycrossplatformservice[Install]
WantedBy=multi-user.target
确保将 /path/to/your/publish 替换为您实际的发布路径。
6.2 启用和启动服务
执行以下命令启用并启动服务:
sudo systemctl enable mycrossplatformservice
sudo systemctl start mycrossplatformservice
6.3 检查服务状态
您可以使用以下命令检查服务的状态:
sudo systemctl status mycrossplatformservice
7. 日志记录
7.1 配置日志记录
在 Worker 中,我们使用了 ILogger<Worker> 来记录信息。在 Visual Studio 中,您可以通过 appsettings.json 文件配置日志记录设置。例如:
{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"AllowedHosts": "*"
}
我们也可以使用log4net、NLog等第三方日志库来记录日志,尤其是log4net非常的强大,具体使用在此不进行具体介绍,因为网络上资源很多了。
8. 高级特性与扩展
在完成基本服务后,可以通过以下方式进一步增强服务的功能和可维护性:
8.1 使用依赖注入
您可以通过依赖注入来实现服务间的解耦。
添加自定义服务
- 创建一个新的接口和实现:
public interface IMyService {void DoWork(); }public class MyService : IMyService {public void DoWork(){// 自定义逻辑,例如调用 API 或处理数据库操作Console.WriteLine("MyService is working...");} } - 在
Program.cs中注册该服务:services.AddTransient<IMyService, MyService>(); - 在
Worker.cs中使用该服务:private readonly IMyService _myService;public Worker(ILogger<Worker> logger, IMyService myService) {_logger = logger;_myService = myService; }protected override async Task ExecuteAsync(CancellationToken stoppingToken) {while (!stoppingToken.IsCancellationRequested){_myService.DoWork();_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);await Task.Delay(1000, stoppingToken);} }
8.2 配置管理
.NET Core 和 .NET 6 提供了强大的配置管理系统,可以通过 appsettings.json 文件或环境变量来进行配置管理。可以将配置注入到服务中以根据不同环境进行调整。
添加配置文件 appsettings.json
创建 appsettings.json 文件,并在其中添加所需的配置项,例如:
{"MyServiceConfig": {"Setting1": "Value1","Setting2": "Value2"}
}
使用配置
在 Program.cs 中加载配置:
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((context, config) =>{config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);}).ConfigureServices((hostContext, services) =>{services.Configure<MyServiceConfig>(hostContext.Configuration.GetSection("MyServiceConfig"));services.AddHostedService<Worker>();services.AddTransient<IMyService, MyService>();});
在 Worker.cs 中注入并使用配置:
public class Worker : BackgroundService
{private readonly ILogger<Worker> _logger;private readonly IMyService _myService;private readonly IOptions<MyServiceConfig> _config;public Worker(ILogger<Worker> logger, IMyService myService, IOptions<MyServiceConfig> config){_logger = logger;_myService = myService;_config = config;}protected override async Task ExecuteAsync(CancellationToken stoppingToken){while (!stoppingToken.IsCancellationRequested){_logger.LogInformation("Setting1: {setting1}", _config.Value.Setting1);_myService.DoWork();await Task.Delay(1000, stoppingToken);}}
}public class MyServiceConfig
{public string Setting1 { get; set; }public string Setting2 { get; set; }
}
8.3 健康检查与监控
通过健康检查确保服务的正常运行。
- 在
Program.cs中添加健康检查支持:services.AddHealthChecks(); - 实现自定义健康检查逻辑:
public class MyHealthCheck : IHealthCheck {public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default){bool isHealthy = true; // 检查服务是否正常return isHealthy? Task.FromResult(HealthCheckResult.Healthy("The service is healthy.")): Task.FromResult(HealthCheckResult.Unhealthy("The service is unhealthy."));} } - 在
Program.cs中注册健康检查:services.AddHealthChecks().AddCheck<MyHealthCheck>("My Health Check");
9. 日志持久化
将日志记录到文件、数据库或第三方日志管理系统。
- 安装 Serilog 的 NuGet 包:
dotnet add package Serilog.Extensions.Logging dotnet add package Serilog.Sinks.File - 在
Program.cs中配置 Serilog:using Serilog;public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseSerilog((context, config) =>{config.WriteTo.Console();config.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day);}).ConfigureServices((hostContext, services) =>{services.AddHostedService<Worker>();});
10. 容器化支持
使用 Docker 将服务容器化,便于部署。
10.1 创建 Dockerfile
在项目的根目录下创建一个 Dockerfile:
# 使用官方的 .NET SDK 镜像作为构建阶段
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app# 复制并构建应用程序
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o out# 使用 .NET 运行时镜像作为运行阶段
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app/out .# 启动服务
ENTRYPOINT ["dotnet", "MyCrossPlatformService.dll"]
10.2 构建和运行 Docker 镜像
- 在 Visual Studio 中打开命令提示符,构建 Docker 镜像:
docker build -t mycrossplatformservice . - 运行容器:
docker run -d --name mycrossplatformservice mycrossplatformservice
11. 总结
通过使用 Visual Studio 2022 和 .NET 6,您可以轻松创建一个跨平台的后台服务,支持 Windows、Linux 和 macOS。通过添加依赖注入、健康检查、日志记录和容器化等功能,您可以构建出复杂且高可维护性的跨平台服务。这使得 C# 和 .NET 6 成为构建现代背景服务的理想技术栈。您可以根据需求进一步扩展服务功能,例如数据库连接、API 集成、消息队列等,满足不同业务需求。
相关文章:
使用 .NET 6 构建跨平台 Worker Service 服务:跨越平台的 C# 服务开发——解决Windows服务跨平台问题
现代软件开发中,构建跨平台的应用程序变得愈加重要。C# 和 .NET 6 的出现使得在 Windows、Linux 和 macOS 上创建背景服务变得简单而高效。在本指南中,我们将通过创建一个使用 .NET 6 的 Worker Service 来展示如何实现跨平台后台服务。 项目概述 我们…...
terminator-gnome
gnome import os#启动节点指令变量 stere"ros2 launch stereo_c start.py" utils"ros2 launch task utils.launch.py" #tab标题 stere_title"stere_driver" utils_title"utils"#一个终端界面打开5个tab cmd1f"gnome-terminal --…...
7.测试用例设计方法 + Bug
一、正交实验法 1.使用场景 因果关系比较庞大的情况下,不太适合用因果图判定表,在这种情况下,一般会采用正交实验法。 2.例子: 字符属性设置(4个条件) 字体很多 字符样式很多 …...
uniapp小程序,使用腾讯地图获取定位
本篇文章分享一下在实际开发小程序时遇到的需要获取用户当前位置的问题,在小程序开发过程中经常使用到获取定位功能。uniapp官方也提供了相应的API供我们使用。 官网地址:uni.getLocation(OBJECT)) 官网获取位置的详细介绍这里就不再讲述了,大…...
Reactive 编程-Project Reactor
Reactive 编程与 Project Reactor Reactive 编程是一种编程范式,主要用于处理异步数据流。它旨在通过声明式的编程方式处理事件驱动的非阻塞任务,特别适合于构建响应式、可扩展、高并发的应用。随着互联网应用规模的扩大和响应速度的提升需求࿰…...
splice用法
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
Redis - 缓存
文章目录 目录 文章目录 1. 什么是缓存? 2. 使用Redis作为缓存 2.1 关系型数据库的缺点 3. 缓存的更新策略 3.1 定期生成 3.2 实时生成 缓存淘汰策略 4. 缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿 缓存预热 缓存穿透 缓存雪崩 缓存击穿 总结 1. 什么…...
基于SpringBoot+Vue的养老院管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…...
多线程爬虫接入代理IP:高效数据抓取的秘诀
在现代网络环境中,爬虫已经成为获取信息的利器。然而,随着网站反爬措施的不断升级,单线程爬虫往往无法满足需求。多线程爬虫与代理IP的结合,不仅能提高效率,还能有效规避IP封禁问题。本文将详细探讨多线程爬虫接入代理…...
[网络][CISCO]Cisco-PIX配置详解
Cisco PIX防火墙配置指南 任何企业安全策略的一个主要部分都是实现和维护防火墙,因此防火墙在网络安全的实现当中扮演着重要的角色。防火墙通常位于企业网络的边缘,使内部网络与Internet之间或与其他外部网络互相隔离,并限制网络互访&#x…...
拒绝千篇一律,AI帮你定制独一无二的个人写真
每个女人都渴望展现最美的自己,你是否厌倦了拍出千篇一律的照片?今天,我要告诉你一个秘密,用简单三步,即可打造属于你的独一无二个人写真!文生图、蒙版换脸、图生图,三步化身超级模特࿰…...
在云服务器上安装 RabbitMQ:从零到一的最佳实践
🛠 1. RabbitMQ 简介 RabbitMQ 是一个开源的消息代理中间件,广泛应用于高并发、异步任务队列的场景中。在分布式系统架构中,RabbitMQ 可以充当消息的中转站,帮助不同服务之间进行高效的消息通信。 在这篇文章中,我们…...
【nginx】搭配okhttp 配置反向代理
nginx的默认是一个反向代理。 nginx会默认把输入的请求,转向其他的服务器执行。 这些转向的服务器与客户端发起的服务器不是同一个。 客户端只认识nginx,不知道ngiix转向何方。 正向代理修改okhttp的proxy,实际上很多代理都是正向的。 反向代理修改请求路径到nginx。 感觉还…...
Android V 广播注册和配置注意事项问题
现象 在Android V平台上,应用注册非Protected广播时,如果没有加导出flag会抛出异常导致进程crash。 E/AndroidRuntime: FATAL EXCEPTION: main java.lang.SecurityException: com.demo.myapplication: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORT…...
深入解读Docker核心原理:Namespace资源隔离机制详解
在容器技术中,资源隔离 是容器化能够实现轻量级虚拟化的关键技术之一。通过资源隔离,容器可以拥有自己的独立环境,确保容器之间互不干扰,从而实现应用的安全和稳定。Docker作为主流的容器平台,其核心的资源隔离机制依赖…...
学习通、智慧职教刷课脚本
🐐个人主页 可惜已不在 🐋可以分享给身边有需要的人🐶 🐉有用的话就留下一个三连吧😼 目录 一.安装 脚本运行器 篡改猴 - Microsoft Edge Addons 二.安装脚本 三.扩展 一.安装 脚本运行器 安装浏览器 Microsoft E…...
SEO写作:从实战到精进的全方位指南
在数字化浪潮中,SEO不再是简单的关键词堆砌,而是成为企业品牌建设与市场拓展的核心策略。作为一名深耕SEO领域的实践者,我深知其中的门道与奥秘。今天,我将结合过往实战经验,以独特视角,带你一窥SEO写作的精…...
解决 git 不是内部或外部命令,也不是可运行的程序
目录 报错提示: 一、解决办法 1、从git官网下载windows版本的git 2、安装 3、注意事项 二、报错 1、解决 fatal: Not a git repository (or any of the parent directories): .git 问题 报错提示: 一、解决办法 Windows下配置Git: 1…...
【卷起来】VUE3.0教程-07-异步请求处理(springboot后端)
🌲 服务端接口准备 pom文件,引入mybatis/mybatis-plus相关依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>&…...
初一信息科技2024指南辅助教学软件(抓包软件)
专门针对信息科技20204指南写的程序,互联网和直播等知识中包含tcp/ip和udp,三次握手等原理,需要简单明了的实验来说明,在机房中需要用抓包软件,可能需要安装windump npcap等软件非常繁琐,还需要接触保护卡&…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
