Dies ist etwas, was ich vor ein paar Tagen entdeckt habe. Ich erhielt die Bestätigung, dass es nicht nur auf meine Maschine von dieser Frage beschränkt ist.
Die einfachste Möglichkeit, dies zu wiederholen, besteht darin, eine Windows Forms-Anwendung zu starten, eine Schaltfläche hinzuzufügen und den folgenden Code zu schreiben:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Das Programm schlägt fehl after die Exit () - Anweisung wird ausgeführt. In Windows Forms erhalten Sie "Fehler beim Erstellen des Fensterhandles".
Durch die Aktivierung von nicht verwaltetem Debugging wird etwas klarer, was los ist. Die COM modal-Schleife wird ausgeführt und ermöglicht die Übermittlung einer WM_Paint-Nachricht. Das ist auf einer abgelegten Form tödlich.
Die einzigen Fakten, die ich bisher gesammelt habe, sind:
Mich interessiert besonders, was Sie tun könnten, um diesen Absturz zu vermeiden. Insbesondere das Szenario AppDomain.UnhandledException stummelt mich; Es gibt nicht viele Möglichkeiten, ein .NET-Programm zu beenden. Beachten Sie bitte, dass das Aufrufen von Application.Exit () oder Form.Close () in einem Event-Handler für UnhandledException nicht gültig ist. Es handelt sich also nicht um Problemumgehungen.
UPDATE: Mehrdad wies darauf hin, dass der Finalizer-Thread ein Teil des Problems sein könnte. Ich glaube, ich sehe das und sehe auch Beweise für das 2-Sekunden-Timeout, das die CLR dem Finalizer-Thread gibt, um die Ausführung abzuschließen.
Der Finalizer befindet sich in NativeWindow.ForceExitMessageLoop (). Es gibt dort eine IsWindow () - Win32-Funktion, die ungefähr der Codestelle entspricht, 0x3c versetzt, wenn der Maschinencode im 32-Bit-Modus betrachtet wird. Es scheint, dass IsWindow () Deadlocking ist. Ich kann keine gute Stack-Spur für die Interna bekommen, der Debugger meint jedoch, dass der Aufruf von P/Invoke gerade zurückgegeben wurde. Das ist schwer zu erklären. Wenn Sie eine bessere Stapelverfolgung erhalten, würde ich es gerne sehen. Bergwerk:
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.ForceExitMessageLoop() + 0x3c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Finalize() + 0x16 bytes
[Native to Managed Transition]
[email protected]@12() + 0xe bytes
[email protected]() + 0x27 bytes
[email protected]() + 0x1b bytes
Nichts über dem ForceExitMessageLoop-Aufruf, nicht verwalteter Debugger aktiviert.
Ich habe mich wegen dieses Problems an Microsoft gewandt und das schien sich ausgezahlt zu haben. Zumindest würde ich gerne glauben, dass es so war :). Obwohl ich von ihnen keine Bestätigung einer Auflösung erhalten habe, ist es schwierig, die Windows-Gruppe direkt zu kontaktieren, und ich musste einen Vermittler einsetzen.
Ein über Windows Update bereitgestelltes Update hat das Problem behoben. Die spürbare Verzögerung von 2 Sekunden vor dem Absturz ist nicht mehr vorhanden, was darauf hindeutet, dass der Deadlock von IsWindow () behoben wurde. Und das Programm wird sauber und zuverlässig heruntergefahren. Das Update installierte Patches für Windows Defender, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll und wintrust.dll
Uxtheme.dll ist die ungerade Ente. Es implementiert die Visual Styles-Themen-API und wird von diesem Testprogramm verwendet. Ich kann nicht sicher sein, aber mein Geld ist die Ursache des Problems. Die Kopie in C:\WINDOWS\system32 hat die Versionsnummer 6.2.9200.16660, die am 14. August 2013 auf meinem Computer erstellt wurde.
Fall abgeschlossen.
Ich weiß nicht, warum es nicht funktioniert "mehr" , aber ich denke, Environment.Exit
führt ausstehende Finalizer aus. Environment.FailFast
nicht.
Es könnte sein, dass Sie (aus irgendeinem bizarren Grund) seltsame ausstehende Finalizer haben, die danach laufen müssen, was dazu führt, dass dies geschieht.
Dies erklärt nicht, warum es passiert, aber ich würde Environment.Exit
nicht in einem Button-Event-Handler wie Ihrem Beispiel aufrufen. Schließen Sie stattdessen das Hauptformular, wie in rene's answer vorgeschlagen.
Als AppDomain.UnhandledException
-Handler könnten Sie vielleicht einfach Environment.ExitCode
einstellen, anstatt Environment.Exit
aufzurufen.
Ich bin nicht sicher, was Sie hier erreichen wollen. Warum möchten Sie einen Beendigungscode aus einer Windows Forms-Anwendung zurückgeben? Normalerweise werden Beendigungscodes von Konsolenanwendungen verwendet.
Mich interessiert besonders, was Sie tun könnten, um diesen Absturz zu vermeiden Das Aufrufen von Environment.Exit () ist erforderlich, um zu verhindern, dass der WER-Dialog angezeigt wird.
Hast du einen Versuch/Fang in der Main-Methode? Für Windows Forms-Anwendungen habe ich immer einen Try/Catch um die Meldungsschleife sowie die nicht behandelten Ausnahmebehandlungsroutinen.
Ich habe dasselbe Problem in unserer App gefunden, wir haben es mit dem folgenden Konstrukt gelöst:
Environment.ExitCode=1;
Application.Exit();