2009-02-09 9 views
5

Unsere Code-Bibliothek muss benachrichtigt werden, wenn die Anwendung beendet wird. Also haben wir das System.Window.Forms.Application.ApplicationExit-Ereignis abonniert. Dies funktioniert gut für Winforms-Apps, aber funktioniert es auch für andere Arten von Anwendungen wie Konsolen-Apps, Dienste und Web-Anwendungen (wie ASP.NET)? Der Namespace würde darauf hinweisen, dass dies nicht der Fall ist, und wird vermutlich ausgelöst, wenn Application.Exit() aufgerufen wird (explizit oder implizit), was für diese anderen Fälle möglicherweise nicht korrekt ist.Funktioniert das Application.ApplicationExit-Ereignis, um in Anwendungen außerhalb von Winforms über den Exit benachrichtigt zu werden?

Gibt es ein anderes Ereignis, das in diesen anderen Fällen besser wäre oder das universeller wäre (großartig, wenn es auch für Winforms funktioniert)? Gibt es beispielsweise ein Ereignis, wenn Environment.Exit() aufgerufen wird (Konsolen-App)?

fand ich eine Erwähnung eines Exited Ereignis in System.Diagnostic.Process, aber dies scheint für die Überwachung der Ausfahrt andere Prozess, und es scheint nicht durch einen Prozess über sich selbst empfangen zu werden (zB , Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;). Ich würde denken, dass es erst nach dem Prozess ausgelöst werden könnte, so dass es nicht funktionieren würde.

Dies ist insbesondere für .NET 2.0 und C#.

Antwort

9

Wir haben endlich mehr darüber gefunden (aber bis dahin wurde meine Maschine umgebaut und die Cookies an mein nicht registriertes Profil hier verloren; hoffentlich wird es sich erlauben, diese Antwort zu posten).

Weitere Untersuchungen fanden schließlich noch ein paar Ereignisse, die wir nützlich gefunden haben:

System.Windows.Forms.Application.ThreadExit - Wird ausgelöst, wenn eine Nachrichtenschleife verlässt System.Windows.Forms.Application.ApplicationExit - Wird ausgelöst, wenn alle Nachrichten Ausfahrt Schleifen System.AppDomain.CurrentDomain.DomainUnload - Wird ausgelöst, wenn eine andere Domäne als die Standard Exits System.AppDomain.CurrentDomain.ProcessExit - Wird ausgelöst, wenn die Standard-App-Domäne beendet wird System.AppDomain.CurrentDomain.UnhandledException - Wird ausgelöst, wenn eine nicht abgefangene Ausnahme auftritt und die App beendet wird.

Nur einer der Ereignisse DomainUnload oder ProcessExit ist für eine bestimmte Anwendungsdomäne möglich, abhängig davon, ob es sich um die Standarddomäne (oberster Ebene) für den Prozess handelt oder als Subdomäne (z. B. auf einem Webserver) erstellt wurde. . Wenn eine Anwendung nicht weiß, was sie sein könnte (wie in unserem Fall), muss sie beide abonnieren, wenn sie das tatsächliche Entladen für sich selbst erfassen möchte. Es scheint auch, dass UnhandledException (was von .NET2 immer tödlich ist) die anderen zwei Ereignisse verhindern kann, so dass ein dritter Fall behandelt werden kann. Diese drei Ereignisse sollten für jede .NET-Anwendung funktionieren.

Es gibt eine Einschränkung, dass die Ausführungszeit für ProcessExit begrenzt ist (etwa 4 Sekunden?), So dass es nicht möglich ist, umfangreiche "endgültige" Arbeit in diesem Ereignishandler zu tun. Es muss etwas sein, was schnell erledigt werden kann.

Die Application Ereignisse gelten nur für WinForms-Anwendungen (wir vermuten, dass sie möglicherweise nicht in reinen WPF-Anwendungen angewendet werden). Die Benennung kann irreführend sein, weil sie nach ihrer grundlegendsten normalen Verwendung benannt sind, die bestimmte Annahmen hat. ThreadExit bezieht sich nicht auf die tatsächliche System.Threading.Thread, sondern eher auf die Nachrichtenschleife (Application.Run())) eines UI-Threads, und ApplicationExit bezieht sich in ähnlicher Weise auf die Sammlung von Anwendungsformularen auf einem oder mehreren UI-Threads. Normalerweise, sobald der Aufruf von Application.Run() zurückkommt, der von der Eintragsmethode eines Threads aufgerufen wird, endet die Eintragsmethode schnell und der Thread selbst endet dann. Und sobald alle UI-Threads beendet sind, ist normalerweise eine WinForms-App fertig und wird beendet.

Ein weiteres bemerkenswertes Ereignis ist das System.Windows.Forms.Application.ThreadException Ereignis. Eine Windows-Nachrichtenschleife kann so konfiguriert werden, dass sie Ausnahmen abfängt, die bei der Verarbeitung einer Nachricht auftreten, und dieses Ereignis senden, anstatt sie als nicht abgefangene (und damit fatale) Ausnahmen zuzulassen. Durch das Abfangen dieser Ausnahmen kann die Nachrichtenschleife (und der Benutzeroberflächen-Thread) weiter ausgeführt werden (nachdem der aktuelle Nachrichtenhandler abgebrochen wurde). Für einen bestimmten Thread kann zu einem gegebenen Thread jederzeit nur ein Subskribent (Subskriptionen überschreiben jeden vorherigen Subskribenten) und er muss konfiguriert werden, bevor ein Formular erstellt und abonniert wird, bevor die Nachrichtenschleife betreten wird. Weitere Informationen finden Sie in der MSDN-Hilfe für dieses Ereignis und System.Windows.Forms.Applicaton.SetUnhandledExceptionMode().