正好杀死在Linux上运行的.NET Core守护程序

use*_*177 32 c# linux service daemon .net-core

我创建了一个在Ubuntu 14.04计算机上作为守护进程运行的.NET Core控制台应用程序.

我想在不强制服务的情况下停止服务,能够处理kill事件.

我怎样才能做到这一点?

Mar*_*ist 44

自从一年前@ Stefano回答以来,.NET Core已经有了很大的发展.在.NET Core 2.0中,您现在可以使用众所周知的AppDomain.CurrentDomain.ProcessExit事件而不是AssemblyLoadContext.Default.Unloading.它适用于Linux上的控制台应用程序,也适用于Docker.

  • `AppDomain.CurrentDomain.ProcessExit`只允许2秒的清理,并且无法使用托管代码覆盖它. (5认同)
  • @Parag文章是有关ProcessExit事件的,而不是时间限制。在紫色的“注释”框中,它清楚地表明该时限在.NET Core中不存在,我很惊讶您错过它。 (3认同)

Ste*_*nio 26

您希望能够将SIGTERM发送到正在运行的进程:

kill <PID>
Run Code Online (Sandbox Code Playgroud)

并且该过程应该处理它以正确关闭.

不幸的是,.NET Core没有很好的文档记录,但它能够处理Unix信号(以与Mono不同的方式).GitHub问题

如果你使用UbuntuUpstart,你需要的是一个init脚本,它在一个停止请求上发送kill信号:示例init脚本

project.json添加依赖项:

"System.Runtime.Loader": "4.0.0"
Run Code Online (Sandbox Code Playgroud)

这将为您提供AssemblyLoadContext.

然后你可以处理SIGTERM事件:

AssemblyLoadContext.Default.Unloading += MethodInvokedOnSigTerm;
Run Code Online (Sandbox Code Playgroud)

注意:

使用Mono,正确的处理方式是通过UnixSignal:Mono.Unix.Native.Signum.SIGTERM

编辑:

正如@Marc在他最近的回答中指出的那样,这不再是实现这一目标的最佳方式.来自.NET Core 2.0 AppDomain.CurrentDomain.ProcessExit是受支持的事件.

  • 尝试访问已发布的DLL文件夹并运行:`dotnet <DllName> .dll`(不运行)应该只运行一个进程,您可以尝试查杀该进程. (2认同)