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émenterWebHostBuilder()
ne convient pas.
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.
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 */};
À 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
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);
}
}
}