像Windows服务一样托管.NET Core控制台应用程序

3
我的工作进程是一个 .net core 控制台应用程序。我该如何像 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();
    }
}

这是一个ASP.NET Core应用程序还是标准的.NET Core控制台应用程序?如果是,有一些方法可以将.NET控制台应用程序作为Windows服务“托管”(不像内置的ASP.NET Core方法那么容易)http://www.ben-morris.com/running-a-net-core-console-application-as-a-windows-service/ - d.moncada
2个回答

16

在.NET Core 2.1中,您可以使用泛型主机(Generic Host)类创建和运行服务或守护程序应用程序。

您可以几乎以与ASP.NET Core应用程序相同的方式配置和运行应用程序。尽管文章标题是这样,但这不仅限于ASP.NET Core,泛型主机生成器是通过Microsoft.Extensions.Hosting包部署的,该包没有ASP.NET Core依赖项。

主方法可能如下所示:

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 接口。详见使用托管服务进行后台任务

UseConsoleLifetime() 方法可配置主机以检查 Ctrl+C 并终止应用程序。在此情况下,主机将调用任何已配置服务的实现了 IHostedService 接口的 StopAsync 方法。

调用 RunAsync() 将调用任何实现了 IHostedService 接口的服务的 StartAsync 方法。

还可以调用 RunConsoleAsync() 来配置控制台生存期并启动服务,而无需额外调用 UseConsoleLifetime()

RunAsyncRunConsoleAsync 将阻塞直到主机终止。您可以使用 StartStartAsync 来启动服务并处理控制台输入或外部命令。当需要终止应用程序时,例如响应 exit 输入,可以调用 StopAsync

示例如下:

host.Start();

Console.WriteLine("Type exit or Ctrl+C to exit");
while(Console.ReadLine() !="exit")
{
    //..
}

await host.StopAsync();

当然,这可以用于更重要的事情,例如从端口接收指令。


3

不要使用自定义的停止信号,改用标准的CTRL-C来停止进程。在Console.CancelKeyPress 中有一些示例,展示了如何对该事件做出反应,并在其中放置你的workerService.Stop()语句。

nssm等工具可配置为发送CTRL-C信号以启动服务关闭,而任何包装系统都应该提供类似的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接