Ceci fait suite à ma question initiale et je voudrais présenter mes conclusions et demander des corrections, des idées et des idées. Mes découvertes (ou plutôt interprétations) proviennent des réponses des personnes à ma question précédente, à savoir la lecture de la documentation MSDN .NET 3.5 et le débogage du code .NET 3.5. J'espère que cela sera utile à quelqu'un qui se demandait, comme moi, comment détecter le moment où une application se termine.
Événements:
System.AppDomain.CurrentDomain.ProcessExit
: déclenché à la fin du processus, par ex. après la valeur par défaut AppDomain
et que tout le reste a été déchargé [Le temps d'exécution total est limité à 3 secondes seulement!]. Pour WPF, utilisez plutôt System.Windows.Application.Exit
. Pour Windows Forms, exécutez le code après Application.Run(...)
dans la méthode principale.
System.AppDomain.CurrentDomain.DomainUnload
: déclenché lorsqu'une AppDomain
autre que la valeur par défaut AppDomain
est déchargée, par ex. lors de l'exécution de classes avec des frameworks de tests unitaires (MbUnit with TestDriven.NET).
System.AppDomain.CurrentDomain.UnhandledException
: (si manipulé par défaut AppDomain
:) levé pour toute exception non gérée dans un thread, quelle que soit la forme de AppDomain
dans laquelle le thread a commencé. Cela signifie que cela peut être utilisé comme attrape-tout pour toutes les exceptions non gérées.
System.Windows.Application.Exit
: déclenché lorsque l'application WPF (c'est-à-dire la valeur par défaut AppDomain
) se ferme normalement. Remplacez System.Windows.Application.OnExit
pour en tirer parti.
Finalizers (destructeurs en C #): exécutés lorsque le ramasse-miettes libère des ressources non gérées. [Le temps d'exécution total est limité!].
Ordre des événements:
Application WPF: sortie en douceur
System.Windows.Application.Exit
System.AppDomain.CurrentDomain.ProcessExit
Application WPF: exception non gérée
System.AppDomain.CurrentDomain.UnhandledException
MbUnit en cours d'exécution dans TestDriven.NET: test réussi (sortie en douceur)
System.AppDomain.CurrentDomain.DomainUnload
MbUnit s'exécutant dans TestDriven.NET: échec du test (les exceptions non gérées sont gérées par MbUnit)
AppDomain.CurrentDomain.DomainUnload
Questions:
Invité par la question/réponse de ssg31415926 (cette question est un peu inversée), il y a aussi Application.SessionEnding qui est appelé lorsque l'utilisateur ferme ou ferme la session. Il est appelé avant l'événement de sortie.
Lorsque Dispatcher.BeginInvokeShutdown()
est appelé, Application.Exit
ne sera pas appelé.
Vous écrivez:
System.AppDomain.CurrentDomain.UnhandledException: (si gérée par défaut par AppDomain :), levée pour toute exception non gérée dans un thread, quelle que soit la méthode utilisée par AppDomain dans le thread. .
Je ne pense pas que cela soit correct. Essayez le code suivant:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AppDomainTestingUnhandledException
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, eventArgs) => Console.WriteLine("Something went wrong! " + args);
var ad = AppDomain.CreateDomain("Test");
var service =
(RunInAnotherDomain)
ad.CreateInstanceAndUnwrap(
typeof(RunInAnotherDomain).Assembly.FullName, typeof(RunInAnotherDomain).FullName);
try
{
service.Start();
}
catch (Exception e)
{
Console.WriteLine("Crash: " + e.Message);
}
finally
{
AppDomain.Unload(ad);
}
}
}
class RunInAnotherDomain : MarshalByRefObject
{
public void Start()
{
Task.Run(
() =>
{
Thread.Sleep(1000);
Console.WriteLine("Uh oh!");
throw new Exception("Oh no!");
});
while (true)
{
Console.WriteLine("Still running!");
Thread.Sleep(300);
}
}
}
}
Autant que je sache, le gestionnaire UnhandledException n'est jamais appelé, et le thread va juste planter en silence (ou vous harceler si vous l'exécutez dans le débogueur).
Ajoutez simplement un nouvel événement sur votre formulaire principal:
private void frmMain_Load(object sender, EventArgs e)
{
Application.ApplicationExit += new EventHandler(this.WhenItStopsDoThis);
}
private void WhenItStopsDoThis(object sender, EventArgs e)
{
//Program ended. Do something here.
}