C# 当UnhandledExceptionMode设置为UnhandledExceptionMode.Automatic时,哪个.config元素会影响异常处理?

C# 当UnhandledExceptionMode设置为UnhandledExceptionMode.Automatic时,哪个.config元素会影响异常处理?,c#,winforms,configuration,C#,Winforms,Configuration,我有一个Windows窗体应用程序,程序启动时有以下代码: Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); 其MSDN文档中指出: 自动-将所有异常路由到 ThreadException处理程序,除非 应用程序的配置文件 另有规定 有人确切地知道配置文件中的哪个元素/属性会影响此设置吗?我也想知道这一点,但我从来没有找到任何关于您可以设置的任何特定内置配置选项的信息(可能有一个,但我从来没有提到它

我有一个Windows窗体应用程序,程序启动时有以下代码:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);
其MSDN文档中指出:

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


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

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

但是,我确实发现有两个重载
SetUnhandledExceptionMode
。正常的设置是基于每个线程(通常只有一个UI线程),但第二个设置也采用布尔值,该布尔值确定设置是仅应用于当前线程(true)还是应用于所有UI线程(false)。传递false的行为类似于为将来的UI线程设置默认设置,如果它们在启动时保持在
自动
模式(我指的是消息循环,即调用
应用程序.Run
),您可以将自己的配置选项挂接到该调用中,以设置全局默认值。我不得不怀疑,他们是否真的在使用模糊的“配置”引用

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

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


然而,
AppDomain.UnhandledException
是多个订阅服务器的正常事件,并且不是特定于线程的。订阅一次,您就可以访问整个AppDomain(例如CurrentDomain)。

您可以向配置文件中添加一个JITDebuging部分,如下所示:

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

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

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


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

感谢您添加链接,Martin。我花了几分钟才弄清楚您更改了什么,因为编辑历史记录没有突出显示元数据中的更改。现在我看到了如何在这里做链接;我不可能通过反复试验就明白这一点!不幸的是,我们都在等待关于您的特定问题的最终答案。因此,添加该配置以启用JITDebuging(默认情况下为false,对吗?)会将模式切换为(有效地)ThroweException,使异常不被消息循环处理,从而使其成为未处理的异常,如果用户从弹出窗口中选择,则可以在此时激活应用程序的调试。我有这个权利吗?我认为这最终解释了《博士》中那条神秘的线,并回答了马丁最初的问题+1因为这个问题也困扰着我。我终于骄傲地更深入地研究了这个问题。虽然这是有效果的环境,但它是否有效果有点复杂。还依赖于DebuggableAttribute上IsJITDebugLaunchSetting标志的值和以下两个注册表项:HKLM