Dies ist etwas, das ich erst vor ein paar Tagen entdeckt habe. Ich habe durch diese Frage die Bestätigung erhalten, dass es nicht nur auf meine Maschine beschränkt ist .
Der einfachste Weg, dies zu reproduzieren, besteht darin, eine Windows Forms-Anwendung zu starten, eine Schaltfläche hinzuzufügen und diesen Code zu schreiben:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Das Programm schlägt fehl, nachdem die Anweisung Exit () ausgeführt wurde. Unter Windows Forms wird "Fehler beim Erstellen des Fensterhandles" angezeigt.
Durch Aktivieren des nicht verwalteten Debuggens wird deutlich, was los ist. Die COM- Modalschleife wird ausgeführt und ermöglicht die Zustellung einer WM_PAINT-Nachricht. Das ist auf einer entsorgten Form fatal.
Die einzigen Fakten, die ich bisher gesammelt habe, sind:
- Es ist nicht nur auf die Ausführung mit dem Debugger beschränkt. Dies schlägt auch ohne fehl. Eher schlecht wird der WER-Absturzdialog auch zweimal angezeigt .
- Es hat nichts mit der Bitterkeit des Prozesses zu tun. Die wow64-Ebene ist ziemlich berüchtigt, aber ein AnyCPU-Build stürzt auf die gleiche Weise ab.
- Es hat nichts mit der .NET-Version zu tun. 4.5 und 3.5 stürzen auf die gleiche Weise ab.
- Der Exit-Code spielt keine Rolle.
- Das Aufrufen von Thread.Sleep () vor dem Aufrufen von Exit () behebt das Problem nicht.
- Dies geschieht unter der 64-Bit-Version von Windows 8, und Windows 7 scheint nicht in gleicher Weise betroffen zu sein.
- Dies sollte ein relativ neues Verhalten sein, das habe ich noch nie gesehen. Ich sehe keine relevanten Updates, die über Windows Update bereitgestellt werden , obwohl der Update-Verlauf auf meinem Computer nicht mehr korrekt ist.
- Dies ist ein grob brechendes Verhalten. Sie würden Code wie diesen in einen Ereignishandler für AppDomain.UnhandledException schreiben, und er stürzt auf die gleiche Weise ab.
Ich bin besonders daran interessiert, was Sie möglicherweise tun könnten, um diesen Absturz zu vermeiden. Besonders das Szenario AppDomain.UnhandledException macht mich fertig; Es gibt nicht viele Möglichkeiten, ein .NET-Programm zu beenden. Beachten Sie, dass das Aufrufen von Application.Exit () oder Form.Close () in einem Ereignishandler für UnhandledException nicht gültig ist und daher keine Problemumgehungen darstellt.
UPDATE: Mehrdad wies darauf hin, dass der Finalizer-Thread Teil des Problems sein könnte. Ich denke, ich sehe dies und sehe auch einige Beweise für das 2-Sekunden-Timeout, dass die CLR dem Finalizer-Thread die Ausführung gibt.
Der Finalizer befindet sich in NativeWindow.ForceExitMessageLoop (). Dort gibt es eine IsWindow () Win32-Funktion, die in etwa der Codeposition entspricht und 0x3c versetzt, wenn der Maschinencode im 32-Bit-Modus betrachtet wird. Es scheint, dass IsWindow () blockiert. Ich kann jedoch keine gute Stapelverfolgung für die Interna erhalten. Der Debugger glaubt, dass der P / Invoke- Aufruf gerade zurückgegeben wurde. Das ist schwer zu erklären. Wenn Sie eine bessere Stapelverfolgung erhalten können, würde ich sie 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]
kernel32.dll!@BaseThreadInitThunk@12() + 0xe bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Nichts über dem ForceExitMessageLoop-Aufruf, nicht verwalteter Debugger aktiviert.
This happens on the 64-bit version of Windows 8Hans hat es gesagt!
Exit(0)vor einiger Zeit mit 64-Bit-Win7, Ändern, festgestelltExitCode hat jetzt nicht geholfen, es Process.GetCurrentProcess().Kill()ohne Probleme zu verwenden