这是我几天前发现的,我从this question得到了确认,它不仅仅局限于我的机器。
重现它的最简单方法是启动Windows窗体应用程序,添加一个按钮并编写以下代码:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
执行Exit()语句后,程序会失败。在Windows窗体上,您会看到“创建窗口句柄时出错”。
启用非托管调试可以使所发生的事情变得更加清晰。COM模式循环正在执行,并允许传递WM_PAINT消息。在已处理的表单上,这是致命的。
到目前为止,我收集到的唯一事实是:
我特别感兴趣的是,您可以做些什么来避免这种崩溃。特别是AppDomain.UnhandledException场景把我难倒了;终止.NET程序的方法并不多。请注意,调用Application.Exit()或Form.Close()在UnhandledException的事件处理程序中无效,因此它们不是解决方法。
更新: Mehrdad指出终结器线程可能是问题的一部分。我想我看到了这一点,也看到了CLR给终结器线程2秒超时来完成执行的一些证据。
终结器在NativeWindow.ForceExitMessageLoop()中。这里有一个IsWindow() Win32函数,它大致对应于在32位模式下查看机器代码时的代码位置,偏移量为0x3c。看起来IsWindow()是死锁的。我不能很好地跟踪内部的堆栈,但是调试器认为P/Invoke调用刚刚返回。这很难解释。如果你能得到一个更好的堆栈跟踪,那么我很乐意看到它。我的:
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
ForceExitMessageLoop调用之上没有任何内容,已启用非托管调试器。
https://stackoverflow.com/questions/18036863
复制相似问题