web-dev-qa-db-fra.com

Comment faire pour arrêter gracieusement sur dotnet avec docker?

Existe-t-il un moyen de gracieusement d’arrêter une application DOTNET CORE qui s’exécute dans DOCKER? Si oui, quel événement devrais-je écouter?

Tout ce que je veux, c’est lors de la demande d’annulation que je souhaite transmettre mon/mes jetons d’annulation aux méthodes actuelles et reporter l’arrêt pendant leur fonctionnement.

Vous recherchez un exemple de code, lien de référence, etc. qui concerne le noyau dotnet et non des informations génériques

UPDATECette question n'est pas un doublon de le conteneur docker se ferme immédiatement, même avec Console.ReadLine () dans une application de console .net principale parce que je n'ai pas de problème de sortie immédiat. J'ai besoin de puiser dans quelque chose comme Windows.SystemsEvents.SessionEnding et m'appuyer sur Console.CancelKeyPress et/ou implémenter WebHostBuilder() ne convient pas.

14
cilerler

Dans .NET Core 2.0, vous pouvez utiliser l'événement AppDomain.CurrentDomain.ProcessExit, qui fonctionne parfaitement sous Linux dans Docker. AssemblyLoadContext.Default.Unloading fonctionne probablement aussi, même avant .NET Core 2.0.

7
Marc Sigrist

System.Console a un événement appelé CancelKeyPress. Je crois que cela est déclenché lorsqu'un événement sigint est passé dans dotnet.

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

À l’aide de 2.0.0-preview2-006497 J’ai effectué des tests. Le AssemblyLoadContext.Default.Unloading est déclenché lorsque Docker envoie un SIGTERM/SIGINT au conteneur.

Exemple de code ressemble à:

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

Voir aussi ce numéro pour quelques détails: https://github.com/aspnet/Hosting/issues/870

2
Stef Heyenrath

Si votre conteneur est exécuté sous Linux, Loader.AssemblyLoadContext.Default.Unloading fonctionne, car il peut intercepter le signal SIGTERM. Toutefois, Windows ne dispose pas du mécanisme équivalent pour cela ( dotnet issue ). Voici une réponse pour gérer la notification d'arrêt dans Windows en utilisant SetConsoleCtrlHandler à partir de Gist

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