首先是一些背景:我有一个多线程WinForms应用程序正在与本机dll互操作。这个应用程序有时会因未处理的异常而崩溃,我们正试图调查它为什么会发生。为了方便它,我正在创建一个全局异常处理程序,我计划从中生成进程转储文件。
现在提出疑问:截至目前,这个应用程序已经为Application.ThreadException
提供了处理程序,但它仍然会因未处理的异常而崩溃。我正在考虑为AppDomain.UnhandledException
添加一个处理程序,虽然我不确定它是否会有所帮助。在此方案中是否存在任何可能未被Application.ThreadException
答案 0 :(得分:22)
是的,Application.ThreadException只能捕获UI线程中引发的异常。在由于Windows通知而运行的代码中。或者在技术术语中,由消息循环触发的事件。大多数Winforms事件都符合这一类别。
它做什么 not 陷阱是在任何非UI线程上引发的异常,例如以Thread.Start(),ThreadPool.QueueUserWorkItem或委托的BeginInvoke()方法启动的工作线程。任何未处理的异常将终止应用程序,AppDomain.UnhandledException是最后一次喘息。
进一步下山,使用任何CLR机制无法检测到从未进行任何托管CLR调用的本机代码在非托管线程中引发的硬件异常。 AccessViolation(异常代码0xc0000005)是最常见的死因。捕获它们的唯一方法是通过Windows API,SetUnhandledExceptionFilter()。这很难做对。
您可以使用Application.SetUnhandledExceptionMode()禁用Application.ThreadException。这是明智之举,为用户提供“继续”选项并没有多大意义。现在,托管线程中的所有异常都表现相同,请使用AppDomain.UnhandledException来记录它们。
答案 1 :(得分:8)
Application.ThreadException
只会针对WinForms UI线程上的未处理异常引发(请参阅here。)在这种情况下,为AppDomain.UnhandledException
添加处理程序可能有所帮助(尽管有一些注意事项,如上所述)在备注部分here。)
答案 2 :(得分:3)
我强烈建议您使用OS minidump生成而不是您自己的生成。这有几个原因:
ThreadException
或UnhandledException
启动时,异常堆栈已经解开。在那一点生成一个minidump只会指向处理程序,而不是异常的来源。如果您的应用在现场,请使用WER。如果您正在进行内部测试,请使用ProcDump。您还可以在“错误报告”对话框处于活动状态时复制minidump文件。
P.S。有一些特殊条件 - 最明显的是在进行p / Invoke时 - ThreadException
和UnhandledException
都不起作用。
P.P.S。如果您有可调试的方案,请尝试启用与p / Invoke相关的Managed Debugging Assistants。