问题 如何使用docker优雅地关闭dotnet?


有办法吗? 优雅 关闭a DOTNET CORE 正在运行的应用程序 搬运工人?如果是的话,我应该听哪个活动?

我想要的只是取消请求我想将我的取消令牌传递给当前的方法并在他们工作时推迟关闭。

寻找与dotnet核心相关的示例代码,参考链接等,而不是通用信息

UPDATE   这个问题不是重复的 即使在.net核心控制台应用程序中使用Console.ReadLine(),docker容器也会立即退出 因为我没有立即退出问题。我需要利用类似的事件 Windows.SystemsEvents.SessionEnding 并依靠 Console.CancelKeyPress 和/或实施 WebHostBuilder() 不符合要求。


13195
2017-11-22 12:42


起源

也许这样吗? shazwazza.com/post/aspnet-core-application-shutdown-events - DavidG
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading 也许 - stuartd
@DavidG正在寻找 DOTNET CORE 并不是 ASP.NET核心 它没有 IApplicationLifetime 但是谢谢你的时间! - cilerler
@cilerler你的问题用[asp.net-core]标记 - stuartd
@cilerler是的,你的问题不是关于ASP.Net Core,所以它不应该包含那个标签。添加它只是为了让您的问题更广泛的受众,这不是正确的做法。 - DavidG


答案:


在.NET Core 2.0中,您可以使用 AppDomain.CurrentDomain.ProcessExit 事件,在Docker中的Linux上运行正常。 AssemblyLoadContext.Default.Unloading 即使在.NET Core 2.0之前,它也可能运行良好。


5
2017-11-24 13:44



'docker stop <container id>'将触发AppDomain.CurrentDomain.ProcessExit。需要注意的是,您的代码只需2秒即可处理。看到: docs.microsoft.com/en-us/dotnet/api/... 和 github.com/dotnet/coreclr/issues/2688#issuecomment-394843595 - J. Andrew Laughlin
@ J.AndrewLaughlin:是的,时间因环境而异。例如,在Kubernetes, kubectl delete deployment ... commant似乎触发了SIGTERM,通常允许应用程序大约30秒进行清理。另一方面, kubectl apply ...  过度 现有的部署似乎立即导致SIGKILL,根本没有时间进行清理。不幸的是,关于这些行为的文档很少不存在。 - Marc Sigrist
@cilerler:您的关注点“我需要利用像......这样的事件”似乎已经得到了解答。如果是这样,请标记您选择的答案,以便其他人可以更快地找到答案。谢谢。 - Marc Sigrist


System.Console有一个名为CancelKeyPress的事件。我相信当sigint事件传递到dotnet时会被触发。

System.Console.CancelKeyPress += (s,e) => { /* do something here */};

3
2018-05-05 21:17





运用 2.0.0 preview2-006497 我做了一些测试,现在 AssemblyLoadContext.Default.Unloading 当Docker将SIGTERM / SIGINT发送到容器时触发。

示例代码如下所示:

System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += ctx =>
{
    // code here...
};

有关详细信息,请参阅此问题: https://github.com/aspnet/Hosting/issues/870


1
2017-08-08 19:47



谢谢你在这里告知,我会测试它并告诉你... - cilerler


如果您的容器在Linux中运行那么 Loader.AssemblyLoadContext.Default.Unloading 因为它可以捕获SIGTERM信号,因为Windows没有相应的机制(dotnet问题)。以下是使用Windows在Windows中处理关闭通知的答案 SetConsoleCtrlHandler 最初是从 要旨

namespace Routeguide
{
    using System;
    using System.Threading;
    ...

    class Program
    {
        [DllImport("Kernel32")]
        internal static extern bool SetConsoleCtrlHandler(HandlerRoutine handler, bool Add);

        internal delegate bool HandlerRoutine(CtrlTypes ctrlType);

        internal enum CtrlTypes
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        }

        static void Main(string[] args)
        {
            // do the server starting code
            Start();
            ....

            var shutdown = new ManualResetEvent(false);
            var complete = new ManualResetEventSlim();
            var hr = new HandlerRoutine(type =>
            {
                Log.Logger.Information($"ConsoleCtrlHandler got signal: {type}");

                shutdown.Set();
                complete.Wait();

                return false;
            });
            SetConsoleCtrlHandler(hr, true);

            Console.WriteLine("Waiting on handler to trigger...");

            shutdown.WaitOne();

            Console.WriteLine("Stopping server...");

            // do the server stopping code
            Stop();

            complete.Set();
            GC.KeepAlive(hr);
        }
    }
}

0
2018-03-12 11:28



不适用于.NET Framework 4.5.2和.NET Core 2.0控制台应用程序。 Docker版本18.05.0-ce-win67(18263) - atomaras
对于dotnet核心,您可以使用Microsoft.Extensions.Hosting,检查我的答案:stackoverflow.com/questions/35176091/... - Feiyu Zhou