Csharp/C#教程:Application.ThreadException与AppDomain.UnhandledException分享


Application.ThreadException与AppDomain.UnhandledException

首先是一些背景:我有一个multithreadingWinForms应用程序,它与本机dll互操作。 这个应用程序有时会因未处理的exception而崩溃,我们正试图调查它为什么会发生。 为了方便它,我正在创建一个全局exception处理程序,我计划从中生成进程转储文件。

现在提出问题:截至目前,这个应用程序已经有Application.ThreadException处理程序,但它仍然与未处理的exception崩溃。 我正在考虑为AppDomain.UnhandledException添加一个处理程序,虽然我不确定它是否会有所帮助。 在此方案中是否存在任何可能未被Application.ThreadException捕获的未处理exception?

是的,Application.ThreadException只能捕获UI线程中引发的exception。 在由于Windows通知而运行的代码中。 或者在技术术语中,由消息循环触发的事件。 大多数Winforms事件都适合此类别。

没有捕获的是在任何非UI线程上引发的exception,例如以Thread.Start(),ThreadPool.QueueUserWorkItem或委托的BeginInvoke()方法开始的工作线程。 这些中的任何未处理的exception将终止应用程序,AppDomain.UnhandledException是最后一次喘息。

进一步下山,使用任何CLR机制都无法检测到从未进行任何托管CLR调用的本机代码在非托管线程中引发的硬件exception。 AccessViolation(exception代码0xc0000005)是最常见的死因。 捕获它们的唯一方法是通过Windows API,SetUnhandledExceptionFilter()。 这很难做到。

您可以使用Application.SetUnhandledExceptionMode()禁用Application.ThreadException。 这是明智之举,为用户提供“继续”选项并没有多大意义。 现在,托管线程中的所有exception都表现相同,请使用AppDomain.UnhandledException来记录它们。

Application.ThreadException只会针对WinForms UI线程上的未处理exception引发(请参阅此处 。)在这种情况下,为AppDomain.UnhandledException添加处理程序可能有所帮助(尽管有一些注意事项,如此处的备注部分所述。)

我强烈建议您使用OS minidump生成而不是您自己的生成。 这有以下几个原因:

  1. 从同一个过程中生成一个小型转储是非常有问题的,并不总是可行的。
  2. ThreadExceptionUnhandledException启动时,exception堆栈已经解开。 在那一点生成一个minidump只会指向处理程序,而不是exception的来源。

如果您的应用在现场,请使用WER。 如果您正在进行内部测试,请使用ProcDump 。 您还可以在“错误报告”对话框处于活动状态时复制minidump文件。

PS有一些特殊情况 – 最值得注意的是在执行p / Invoke时 – ThreadExceptionUnhandledException都不起作用。

PPS如果您有可调试方案,请尝试启用与p / Invoke相关的托管调试助手 。

上述就是C#学习教程:Application.ThreadException与AppDomain.UnhandledException分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/986825.html

(0)
上一篇 2021年12月22日
下一篇 2021年12月22日

精彩推荐