我创建了一个在 Ubuntu 14.04 机器上作为守护进程运行的 .NET Core 控制台应用程序。
我想停止服务,而不是强制停止,并能够处理 kill 事件。
我该如何实现这一点?
自@Stefano的回答一年以来,.NET Core已经大大发展。在.NET Core 2.0中,您现在可以使用众所周知的AppDomain.CurrentDomain.ProcessExit
事件,而不是AssemblyLoadContext.Default.Unloading
。它适用于Linux上的控制台应用程序,在Docker中也能正常工作。
AppDomain.CurrentDomain.ProcessExit
方法只允许清理工作进行 2 秒钟,且无法使用托管代码覆盖此行为。 - Paragkill <PID>
而且这个过程应该正确处理关闭。
不幸的是,.NET Core 的文档不够完善,但它有能力处理 Unix 信号(与Mono的方式不同)。GitHub问题
如果你使用的是带有Upstart的Ubuntu,你需要一个初始化脚本,在停止请求时发送kill信号:示例初始化脚本
在project.json中添加依赖项:
"System.Runtime.Loader": "4.0.0"
这将为您提供AssemblyLoadContext。
然后,您可以处理SIGTERM事件:
AssemblyLoadContext.Default.Unloading += MethodInvokedOnSigTerm;
注意:
使用Mono时,正确的处理方式是通过UnixSignal: Mono.Unix.Native.Signum.SIGTERM
编辑:
正如@Marc在他最近的回答中指出的那样,这不再是实现此目的的最佳方式。从.NET Core 2.0开始,支持使用AppDomain.CurrentDomain.ProcessExit
事件。
dotnet <DllName>.dll
(不要加run),这将只运行一个进程,您可以尝试杀死该进程。 - Stefano d'Antonioexec
,所以我快速搜索了一下,找到了这个链接:https://github.com/dotnet/cli/issues/2243 但是我猜测它的行为与dotnet <dll>
类似。 - Stefano d'Antonio
dotnet library.dll
,停止函数则是:kill dotnet library.dll
。 - user4388177dotnet app.dll
。对我们来说,这引起了问题。为了缓解这个问题,我们添加了exec dotnet app.dll
,这有助于将SIGTERM信号传播到dotnet应用程序,而不是让shell脚本直接处理SIGTERM。 - AAATechGuy