1、打开Visual Studio新建项目
2、找到辅助角色服务创建(Visual Studio 2022以下的版本叫Work Service)
3、添加以下项目包,使项目可以发布成Windows服务或Linux守护进程
4、新建需要运行的服务类以及配置类
新建服务类ConfigTest.cs
using Microsoft.Extensions.Options;
using SerilogHelper;
namespace IOT_代理服务.Test
{
public class ServerTest
{
private Logger logger = new("Server");
private readonly IOptions<ConfigTest> options;
public ServerTest(IOptions<ConfigTest> _options)
{
options = _options;
}
/// <summary>
/// 异步任务启动
/// </summary>
public async Task Start(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
logger.AppendLog($"【{options.Value.DirPath}】Test Worker running at:【 {DateTime.Now}】");
await Task.Delay(3000);
}
}
}
}
新建配置类
namespace IOT_代理服务.Test
{
public class ConfigTest
{
/// <summary>
/// 文件夹路径
/// </summary>
public string DirPath { get; set; }
}
}
对应修改appsettings.json文件
{
//配置
"Config": {
//文件夹路径
"DirPath": "12324124123"
}
}
其中的Logging节点我删掉了,我用自己封装的Serilog类
需要的可以参考 .NET 6 使用SeriLog日志类
5、修改Program.cs
using IOT_代理服务;
using IOT_代理服务.Test;
using System.Runtime.InteropServices;
// 作为 Windows Service 运行时,默认的当前工作目录是 C:\WINDOWS\system32,会导致找不到配置文件,
// 所以需要添加下面一行,指定当前工作目录为应用程序所在的实际目录。
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
IHostBuilder builder = Host.CreateDefaultBuilder(args);
//判断当前平台是否是Windows
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
builder.UseWindowsService();
//判断当前平台是否是Linux
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
builder.UseSystemd();
builder.ConfigureServices((context, services) =>
{
// 注册服务
services.AddHostedService<Worker>();
#region 生命周期注册方式
/*
在 ASP.NET Core 中,AddScoped,AddTransient 和 AddSingleton 是三种不同的生命周期注册方式。下面是它们的区别:
AddScoped:表示在一个作用域内只创建一个实例,该作用域的所有请求都将共享同一个实例。这意味着,对于同一个请求,同一类型的服务只会返回同一个实例。例如,在请求处理期间,多个组件可能需要使用相同的服务实例,因此应该使用 AddScoped 注册该服务。
AddTransient:表示每次请求都创建一个新的实例。这意味着,每次请求都会创建一个新的服务实例,不同请求之间不会共享服务实例。例如,如果你需要对每个请求创建一个新的服务实例,那么可以使用 AddTransient 进行注册。
AddSingleton:表示在整个应用程序的生命周期内只创建一个实例,并在之后的每个请求中都会使用该实例。这意味着,对于整个应用程序的生命周期,只有一个实例,该实例会在需要时注入到每个请求中。例如,如果你需要在整个应用程序中使用同一个服务实例,则可以使用 AddSingleton 进行注册。
简而言之,AddScoped 适用于需要在同一请求的多个组件之间共享服务实例,并为此作用域创建新的实例;AddTransient 适用于短期的、轻量级的服务,每次请求都需要使用新的服务实例;而 AddSingleton 则适用于长期运行的服务,整个应用程序都需要使用同一个服务实例。
*/
#endregion 生命周期注册方式
services.AddSingleton<ServerTest>();
// 注册配置
services.Configure<ConfigTest>(context.Configuration.GetSection("Config"));
});
var host = builder.Build();
host.Run();
6、修改Worker.cs
using IOT_代理服务.Test;
using SerilogHelper;
namespace IOT_代理服务
{
public class Worker : BackgroundService
{
private Logger logger = new Logger("Info");
private readonly ServerTest server;
public Worker(ServerTest _server)
{
server = _server;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
// 注册应用启动前需要完成的操作
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
// 注册应用停止前需要完成的操作
return base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// 这里实现实际的业务逻辑
if (!stoppingToken.IsCancellationRequested)
{
//启动测试
Task.Factory.StartNew(() =>
{
server.Start(stoppingToken);
}, TaskCreationOptions.LongRunning);
//启动SignalR客户端
//程序升级
//节点登录/注册
//定时心跳
//看门狗
//配置读取更新
logger.AppendLog("启动任务成功");
await Task.CompletedTask;
}
}
}
}
7、重新生成项目,点击运行,结果如下: