这是我几天前发现的,我从this question确认它不仅限于我的机器。

进行复制的最简单方法是启动Windows Forms应用程序,添加按钮并编写以下代码:

    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("yada");
        Environment.Exit(1);         // Kaboom!
    }

Exit()语句执行后,程序失败。在Windows窗体上,您会收到“错误创建窗口句柄”。

启用非托管调试可以使事情更加清晰。 COM模态循环正在执行,并允许传递WM_PAINT消息。这对处置形式是致命的。

到目前为止,我收集的唯一事实是:
  • 它不仅限于与调试器一起运行。没有一个,这也会失败。同样糟糕的是,WER崩溃对话框显示了两次。
  • 它与进程的琐碎性无关。 wow64层是众所周知的,但是AnyCPU构建会以相同的方式崩溃。
  • 它与.NET版本无关,4.5和3.5崩溃的方式相同。
  • 退出代码无关紧要。
  • 在调用Exit()之前调用Thread.Sleep()无法解决该问题。
  • 这会在Windows 8的64位版本上发生,并且Windows 7似乎不会受到相同的影响。
  • 这应该是相对较新的行为,我之前从未见过。我看不到通过Windows Update传递的相关更新,尽管更新历史记录在我的计算机上不再准确。
  • 这是严重破坏行为。您将在AppDomain.UnhandledException的事件处理程序中编写这样的代码,并且崩溃的方式相同。

  • 我对您为避免发生崩溃可能采取的措施特别感兴趣。尤其是AppDomain.UnhandledException场景使我感到困惑;没有很多方法来终止.NET程序。请注意,在事件处理程序中对UnhandledException调用Application.Exit()或Form.Close()无效,因此它们不是解决方法。

    更新:Mehrdad指出终结器线程可能是问题的一部分。我想我已经看到了这一点,并且还看到了2秒超时的一些证据,表明CLR提供了终结器线程来完成执行。

    终结器位于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调用上方没有任何内容,已启用非托管调试器。

    最佳答案

    我就此问题联系了Microsoft,这似乎已经得到了返回。至少我想这样做:)。尽管我没有从他们那里得到解决方案的确认,但是Windows小组很难直接联系,因此我不得不使用中介。

    通过Windows Update提供的更新解决了该问题。在崩溃之前不再存在明显的2秒延迟,强烈表明IsWindow()死锁已得到解决。并且程序干净可靠地关闭。该更新为Windows Defender,wdboot.sys,wdfilter.sys,tcpip.sys,rpcrt4.dll,uxtheme.dll,crypt32.dll和wintrust.dll安装了补丁

    Uxtheme.dll很奇怪。它实现了Visual Styles主题API,并由该测试程序使用。我不能确定,但​​是我的钱是那个问题的根源。 C:\WINDOWS\system32中的副本的版本号为6.2.9200.16660,于2013年8月14日在我的计算机上创建。

    案件结案。

    关于c# - 为什么Environment.Exit()不再终止程序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18036863/

    10-11 21:59
    查看更多