我的工作进程是一个.net核心控制台应用程序。如何像Windows服务一样托管它?
因为在当前的实现中,我认为如果将其打包为 nssm 之类的东西,它将由于Console.ReadKey()而卡住。但我仍然需要处理停止事件。
public class Program
{
private Program()
{
}
public static void Main()
{
var services = new ServiceCollection();
var startup = new Startup();
startup.ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
var workerService = serviceProvider.GetService<WorkerService>();
workerService.Run();
Console.WriteLine("Listening for messages. Hit any key to quit.");
Console.ReadKey();
workerService.Stop();
}
}
答案 0 :(得分:8)
在.NET Core 2.1中,您可以使用Generic Host类来创建和运行类似应用程序的服务/守护程序。
您几乎可以像配置ASP.NET Core应用程序一样配置和运行应用程序。尽管有文章标题,但这不是特定于ASP.NET Core的,通用主机生成器是通过没有ASP.NET Core依赖性的Microsoft.Extensions.Hosting包进行部署的。
主要方法如下:
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.UseConsoleLifetime()
.ConfigureServices((hostContext, services) =>
{
services.AddLogging();
services.AddHostedService<LifetimeEventsHostedService>();
services.AddHostedService<TimedHostedService>();
})
.Build();
await host.RunAsync();
}
需要在应用程序运行时一直运行的服务应实现IHostedService。 Background tasks with hosted services中对此进行了描述。
UseConsoleLifetime()调用将主机配置为检查Ctrl+C
并终止应用程序。发生这种情况时,主机将调用实现IHostedService
接口的任何已配置服务的StopAsync方法。
调用RunAsync()时,它将调用实现IHostedService的任何服务的StartAsync方法。
您也可以调用RunConsoleAsync()来配置控制台生存期并启动服务,而无需额外调用UseConsoleLifetime()
。
RunAsync
和RunConsoleAsync
将阻塞,直到主机终止。您可以使用Start
或StartAsync来启动服务并继续处理,例如控制台输入或外部命令。当需要终止应用程序时,例如响应exit
输入,您可以调用StopAsync
。
例如:
host.Start();
Console.WriteLine("Type exit or Ctrl+C to exit");
while(Console.ReadLine() !="exit")
{
//..
}
await host.StopAsync();
当然,这可以用于更重要的事情,例如侦听端口上的命令
答案 1 :(得分:2)
使用CTRL-C
的 standard 而不是使用自定义的停止信号来中断您的过程。 Console.CancelKeyPress
中有一些示例显示了如何响应该事件,例如,您可以在其中放置workerService.Stop()
语句。
可以将诸如nssm之类的工具配置为发送CTRL-C
信号以启动服务关闭,并且可以预期,任何包装系统都将提供类似的功能。