【问题标题】:Which .config element affects exception handling with UnhandledExceptionMode set to UnhandledExceptionMode.Automatic?哪个 .config 元素会影响 UnhandledExceptionMode 设置为 UnhandledExceptionMode.Automatic 的异常处理?
【发布时间】:2010-10-07 10:36:24
【问题描述】:

我有一个 Windows 窗体应用程序,它在程序的启动中包含以下代码:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);

UnhandledExceptionMode.Automatic 的 MSDN 文档中指出:

自动 - 将所有异常路由到 ThreadException 处理程序,除非 应用程序的配置文件 另有规定。

有谁确切知道配置文件中的哪个元素/属性会影响此设置?

【问题讨论】:

    标签: c# winforms configuration


    【解决方案1】:

    我也想知道这一点,我从来没有找到任何关于你可以设置的特定内置配置选项的信息(可能有一个,但我从来没有提到它是什么)。我认为我们还发现默认行为(如果您不这样做)等同于 ThrowException 模式,这与 MSDN 在该引用中所暗示的相反。另外,我认为将其设置为“自动”就相当于根本不碰它;它已经在自动开始了。

    但是,我确实发现SetUnhandledExceptionMode 有两个重载。正常的一个在每个线程的基础上运行(通常你只有一个 UI 线程,无论如何),但第二个也需要一个布尔值,它确定该设置是仅应用于当前线程(true)还是应用于所有 UI 线程(错误的)。传递 false 的行为就像为未来的 UI 线程设置默认设置,如果它们在启动时设置为 Automatic 模式(我的意思是消息循环,即调用 Application.Run),您可以挂钩自己的配置选项进行此调用以设置您的全局默认值。我不得不怀疑这是否是他们对模糊的“配置”参考的真正理解。

    但需要注意的是,必须在同一上下文中创建任何窗口句柄之前调用 SetUnhandledExceptionMode。因此,必须在 any 线程上创建任何窗口句柄之前使用 false 调用它。此外,Visual Studio 调试器显然会在您的代码启动之前导致窗口句柄存在,因此在调试时此调用永远不会成功(为 false)。但是,该窗口句柄不在您的线程上,因此可以在调试场景中安全地完成正常调用(或 true)。我不确定在 WinForms 应用程序位于创建的子域而不是作为顶级/初始域的其他情况下,这是如何表现的,无论子域继承了 any-handle-created 标志还是重新开始。也许这就是 Visual Studio 案例中的实际问题。

    在该线程上创建任何窗口句柄之前,仍然必须进行正常调用(或使用 true)。我相信如果您在同一个线程上重新输入Application.Run,此设置将在退出应用程序上下文时持续存在(就像句柄创建的标志一样,它会中断进一步更改它的调用)。但请注意,订阅Application.ThreadException 是基于每个线程、每个上下文的,并且在Application.Run 退出时将丢失。它也可以只有一个订阅者(覆盖任何以前的订阅者),并且在消息循环运行时不能更改。因此,如果您再次调用Application.Run,则必须在调用Application.Run 之前重新订阅Application.ThreadException,否则它们将被捕获并发送到默认的WinForms 处理程序(我不是指UnhandledException),因为“异常模式”设置持续存在。通常,您不会一直在同一个线程上进入和退出消息循环,所以这不是问题,但我们遇到了它,因为我们必须在 Gibraltar.Agent 中这样做。

    AppDomain.UnhandledException,然而,是一个有多个订阅者的正常事件,不是线程特定的。订阅一次,您就可以使用整个 AppDomain(例如 CurrentDomain)。

    【讨论】:

    • 感谢您添加链接,马丁。我花了一些时间才弄清楚您更改了什么,因为编辑历史没有突出显示元数据中的更改。现在我看到了如何在这里做链接;我不会通过反复试验来解决这个问题!不幸的是,我们都还在等待关于您的具体问题的明确答复。
    【解决方案2】:

    您可以像这样在配置文件中添加 JitDebugging 部分:

    <configuration>
      <system.windows.forms jitDebugging="true"/>
    </configuration>
    

    这相当于将 UnhandledExceptionMode 设置为 UnhandledExceptionMode.ThrowException(顺便说一下,如果您运行应用程序时附加了调试器,此选项会自动启用)。

    请注意UnhandledExceptionMode.Automatic 是.Net 使用的默认值,除非您另外指定;据我所知,将 Unhandled Exception Mode 显式设置为 Automatic 的唯一原因是,如果您想撤消之前将其更改为其他内容的调用。请注意,如果您将其设置为自动以外的其他设置,则不会读取配置文件设置。

    请注意,如果您将 ThreadException 附加到当前 AppDomain,则结果会自动如同您将 UnhandledExceptionMode 设置为 UnhandledExceptionMode.CatchException

    【讨论】:

    • 因此,添加该配置以启用 JitDebugging(默认情况下为 false,对吗?)将模式切换为(有效)ThrowException,以便让消息循环未处理异常,从而使其成为UnhandledException 如果用户从弹出窗口中选择,则可以在此时激活应用程序的调试。我有这个权利吗?我认为这最终解释了文档中的那条神秘线并回答了马丁最初的问题。 +1,因为这个问题也困扰着我。
    • 我终于开始更深入地研究这个,虽然这是有效果的设置,但它是否有效果有点复杂。还依赖于 DebuggableAttribute 上的 IsJITDebugLaunchSetting 标志的值和以下两个注册表项:HKLM\Software\Microsoft\.NETFramework -DbgJITDebugLaunchSetting 和 DbgManagedDebugger。
    猜你喜欢
    • 1970-01-01
    • 2013-12-11
    • 2010-11-16
    • 2011-10-07
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多