web-dev-qa-db-ja.com

Dockerを使用してdotnetで正常にシャットダウンする方法は?

/で実行されているDOTNET COREアプリケーションをgracefullyシャットダウンする方法はありますか?[〜#〜] docker [〜#〜]?はいの場合、どのイベントを聞く必要がありますか?

キャンセルリクエストがあれば、キャンセルトークンを現在のメソッドに渡し、それらが機能している間はシャットダウンを延期したいだけです。

一般的な情報ではなく、ドットネットコアに関連するサンプルコード、参照リンクなどを探しています

[〜#〜] update [〜#〜]この質問は docker containerはConsole.ReadLine( ).netコアコンソールアプリケーションで すぐに終了する問題がないため。 Windows.SystemsEvents.SessionEnding のようなイベントを利用する必要があり、_Console.CancelKeyPress_に依存したり、WebHostBuilder()を実装したりすることは適切ではありません。

17
cilerler

.NET Core 2.0では、AppDomain.CurrentDomain.ProcessExitイベントを使用できます。これはLinuxのDockerで正常に機能します。 AssemblyLoadContext.Default.Unloadingは、.NET Core2.0より前でもおそらく同様に機能します。

11
Marc Sigrist

System.Consoleには、CancelKeyPressというイベントがあります。これは、sigintイベントがdotnetに渡されたときに発生すると思います。

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

2.0.0-preview2-006497を使用していくつかのテストを行い、AssemblyLoadContext.Default.UnloadingDockerがSIGTERM/SIGINTをコンテナに送信すると発生します。

サンプルコードは次のようになります。

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

詳細については、この問題も参照してください: https://github.com/aspnet/Hosting/issues/87

2
Stef Heyenrath

コンテナがLinuxで実行されている場合は、Loader.AssemblyLoadContext.Default.Unloading SIGTERMシグナルをトラップできるため機能しますが、Windowsにはこれに相当するメカニズムがありません( dotnet issue )。これは、元々 Gist からSetConsoleCtrlHandlerを使用して、Windowsでシャットダウン通知を処理するための回答です。

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);
        }
    }
}
1
Feiyu Zhou