Mik*_*sen 5 .net docker .net-core docker-for-windows
我很好奇在 Windows 上运行的用 .NET Core 编写的控制台应用程序是否可以拦截 SIGKILL 事件并且基本上知道它正在被终止。这是我正在尝试的代码:
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine($"Hello from PID {Process.GetCurrentProcess().Id}, press CTRL+C to exit.");
AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += context =>
{
Console.WriteLine("SIGTERM received, exiting program...");
};
Console.CancelKeyPress += (s, e) =>
{
Console.WriteLine("SIGINT received, exiting program...");
Environment.Exit(0);
};
try
{
await Task.Delay(Timeout.Infinite);
}
finally
{
Console.WriteLine("Finally executed..");
}
}
Run Code Online (Sandbox Code Playgroud)
当我从命令行运行程序时,我可以使用 CTRL+C 组合键终止它。这将激活CancelKeyPress以及Unloading。如果我以其他方式终止程序(使用 Windows 任务管理器的“结束进程”功能或Stop-ProcessPowerShell 命令),该进程将简单地结束,而不会向控制台写入任何输出。
这是一个更大目标的一部分,即捕获 Docker 容器关闭。在 Windows 上,该docker stop命令将使用 SIGTERM 终止主进程。此行为可在 Linux Docker 上使用--stop-signal或STOPSIGNAL功能进行配置,但这些功能尚未在 Windows 上实现。
在 Windows 上,docker stop 命令将使用 SIGTERM 终止主进程。
从版本开始1803,使用这些基本映像的 Windows 容器将发送CTRL_SHUTDOWN_EVENT到容器中运行的所有进程。
因此,根据您的版本,Docker 可能会发送CTRL_CLOSE_EVENT或CTRL_SHUTDOWN_EVENT.
它们与 Ctrl-C 信号不同,后者是CTRL_C_EVENT. .NET 的Console.CancelKeyPress唯一句柄CTRL_C_EVENT(或密切相关的CTRL_BREAK_EVENT),因此不会调用CTRL_CLOSE_EVENT或CTRL_SHUTDOWN_EVENT。
如果我以其他方式终止程序(使用 Windows 任务管理器的“结束进程”功能或 Stop-Process PowerShell 命令),该进程将简单地结束,而不会向控制台写入任何输出。
不可能处理所有终止信号。我相信任务管理器这些天试图做一个“温和”的关闭,在这种情况下可能是发送CTRL_CLOSE_EVENT,但也完全有可能只是TerminateProcess一个进程,它在没有任何信号或任何东西的情况下立即杀死它。
但是识别 Docker 启动的关闭并对其做出响应是可能的,因为它首先发送一个好的信号并且仅在超时后终止。
.NET 运行时将识别CTRL_CLOSE_EVENT为进程退出请求,但由于 Windows 的 Docker 的较新版本已切换到CTRL_SHUTDOWN_EVENT,我相信.NET 将不再对 Windows 容器进行正常关闭。
我知道的唯一解决方法是安装您自己的控制台控制事件处理程序。我建议处理CTRL_C_EVENT,CTRL_CLOSE_EVENT和CTRL_SHUTDOWN_EVENT所有的只是一个普通的“关机”信号。
| 归档时间: |
|
| 查看次数: |
2803 次 |
| 最近记录: |