为什么Environment.Exit()不终止程序了吗? [英] Why does Environment.Exit() not terminate the program anymore?

查看:1819
本文介绍了为什么Environment.Exit()不终止程序了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我发现的短短数天前,我得到了确认,这不是仅仅局限于我的机器从<一个href="http://stackoverflow.com/questions/18036216/win32exception-was-unhandled-visual-basic-when-click-on-exit-button?noredirect=1#comment26385195_18036216">this问题。

This is something I discovered just a few days ago, I got confirmation that it isn't just limited to my machine from this question.

最简单的方法来瑞普它是通过启动一个WinForms应用程序,添加一个按钮,写这篇code:

The easiest way to repro it is by starting a Winforms application, add a button and write this code:

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

该计划失败的的退出()语句执行。在你的WinForms得到错误创建窗口句柄。

The program fails after the Exit() statement executes. On Winforms you get "Error creating window handle".

启用非托管调试使得它有点清楚这是怎么回事。在COM模式循环正在执行,并允许待递送WM_PAINT消息。这是一个致命的布置形式。

Enabling unmanaged debugging makes it somewhat clear what's going on. The COM modal loop is executing and allows a WM_PAINT message to be delivered. That's fatal on a disposed form.

我到目前为止所收集的唯一事实是:

The only facts I've gathered so far are:

  • 在这不仅仅限于与调试运行。这也失败,没有之一。相当差为好,WER错误对话框显示出来的两次
  • 在它没有什么做的过程中位数,在WOW64层为pretty的臭名昭著而是值为anycpu构建崩溃的方式相同。
  • 在它没有任何关系的.NET版本,4.5和3.5的崩溃一样。
  • 退出code无所谓。
  • 在调用exit()没有解决之前,调用Thread.sleep()方法。
  • 在这种情况发生在64位版本的Windows 8,Windows 7中似乎并没有受到影响相同的方式。
  • 这应该是比较新的行为,我以前没见过这个。我看到通过Windows Update提供任何相关的更新,尽管该更新历史不是我的机器上准确了。
  • 这是严重断裂的行为,你会写code像这样的事件处理程序AppDomain.UnhandledException和崩溃的方式相同。
  • It isn't just limited to running with the debugger. This also fails without one. Rather poorly as well, the WER crash dialog shows up twice.
  • It doesn't have anything to do with the bitness of the process, the wow64 layer is pretty notorious but an AnyCPU build crashes the same way.
  • It doesn't have anything to do with the .NET version, 4.5 and 3.5 crash the same way.
  • The exit code doesn't matter.
  • Calling Thread.Sleep() before calling Exit() doesn't fix it.
  • This happens on the 64-bit version of Windows 8, Windows 7 does not seem to be affected the same way.
  • This should be relatively new behavior, I haven't seen this before. I see no relevant updates delivered through Windows Update, albeit that the update history isn't accurate on my machine anymore.
  • This is grossly breaking behavior, you would write code like this in an event handler for AppDomain.UnhandledException and it crashes the same way.

我在什么你可能做,以避免这种崩溃特别感兴趣。特别是AppDomain.UnhandledException情况下树桩我,不会有很多的方法来终止一个.NET程序。请大家注意,调用Application.Exit()或Form.Close()是不是在事件处理程序UnhandledException无效,因此它们不是解决方法。

I'm particularly interested in what you could possibly do to avoid this crash. Particularly the AppDomain.UnhandledException scenario stumps me, there are not a lot of ways to terminate a .NET program. Please do note that calling Application.Exit() or Form.Close() are not valid in an event handler for UnhandledException so they are not workarounds.

更新:迈赫达德指出,终结器线程可能是问题的一部分。我想我看到这一点,也看到了一些证据,2秒超时的CLR给终结器线程完成执行。

UPDATE: Mehrdad pointed out that the finalizer thread could be part of the problem. I think I'm seeing this, also seeing some evidence for the 2 second timeout that the CLR give the finalizer thread to finish executing.

终结里面NativeWindow.ForceExitMessageLoop()。这里有一个IsWindow()函数WINAPI那里,大致相当于用code的位置,当机器code在32位模式下寻找偏移0x3C符号。似乎IsWindow()被死锁。我不能获得良好的堆栈跟踪的内部然而,调试器认为的PInvoke调用刚刚返回。这是很难解释。如果你能得到一个更好的堆栈跟踪话,我很乐意看到它。我的:

The finalizer is inside NativeWindow.ForceExitMessageLoop(). There's an IsWindow() winapi function there that roughly corresponds with the code location, offset 0x3c when looking at the machine code in 32-bit mode. It seems that IsWindow() is deadlocking. I cannot get a good stack trace for the internals however, the debugger thinks the pinvoke call just returned. This is hard to explain. If you can get a better stack trace then I'd love to see it. Mine:

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电话,非托管调试启用。

Nothing above the ForceExitMessageLoop call, unmanaged debugger enabled.

推荐答案

我联系了微软关于这个问题,而且似乎已经所许关。至少我想,认为它确实:)。虽然我没有得到解决,从他们回来的确认,Windows组难以直接接触,我不得不使用的媒介。

I contacted Microsoft about this problem and that seemed to have payed off. At least I'd like to think it did :). Although I didn't get a confirmation of a resolution back from them, the Windows group is difficult to contact directly and I had to use an intermediary.

通过Windows Update提供的更新解决了这个问题。飞机坠毁前的显着延迟2秒不再是present,强烈提示IsWindow()的僵局得到解决。而程序关闭干净,可靠。已安装的更新补丁的Windows Defender,wdboot.sys,wdfilter.sys,TCPIP.SYS,Rpcrt4.dll中,的uxtheme.dll,crypt32.dll和wintrust.dll

An update delivered through Windows Update solved the problem. The noticeable 2 second delay before the crash is no longer present, strongly suggesting that the IsWindow() deadlock got solved. And the program shuts down cleanly and reliably. The update installed patches for Windows Defender, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll and wintrust.dll

的Uxtheme.dll是奇数鸭子出来,它实现了视觉样式主题化的API,并使用该测试程序。不能肯定,但我的钱是一个为问题的根源。在C副本:\ WINDOWS \ SYSTEM32有版本号6.2.9200.16660,于2013年8月14号在我的机器上创建

Uxtheme.dll is the odd-duck out, it implements the Visual Styles theming api and is used by this test program. Can't be sure but my money is on that one as the source of the problem. The copy in c:\windows\system32 has version number 6.2.9200.16660, created on August 14th, 2013 on my machine.

结案。

这篇关于为什么Environment.Exit()不终止程序了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆