gpt4 book ai didi

c# - 为什么 Environment.Exit() 不再终止程序?

转载 作者:IT王子 更新时间:2023-10-29 03:32:51 31 4
gpt4 key购买 nike

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

重现它的最简单方法是启动一个 Windows 窗体应用程序,添加一个按钮并编写以下代码:

    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() 无法解决问题。
  • 这发生在 64 位版本的 Windows 8 上,Windows 7 似乎没有受到同样的影响。
  • 这应该是比较新的行为,我以前没见过。我没有看到通过 Windows Update 传递的相关更新,尽管更新历史记录在我的机器上不再准确。
  • 这是严重破坏行为。您会在 AppDomain.UnhandledException 的事件处理程序中编写这样的代码,它会以同样的方式崩溃。

我特别感兴趣的是您可以采取哪些措施来避免这次崩溃。特别是 AppDomain.UnhandledException 场景让我很困惑;终止 .NET 程序的方法不多。请注意,调用 Application.Exit() 或 Form.Close() 在 UnhandledException 的事件处理程序中无效,因此它们不是解决方法。


更新: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/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com