我怀疑对此有一个非常简单的解释,但我似乎无法找到它。
当我的WinForms C#4.0应用程序在Program.cs文件中加载自身时,整个Main()函数内部都有一个try / catch语句。
我编写了一个小异常包装器,其行为与vanilla .net“未捕获异常”框非常相似,除了它提供了更多信息,允许保存(序列化)异常树,并允许用户直接向我提交错误报告。
现在,它在调试时工作正常(F5)。如果我在主线程中的程序中触发 where 的异常,如果没有try / catch,则异常会一直触发到Main()并显示自定义窗口。
(我已考虑并妥善处理的所有其他例外情况。)
当我只运行.exe文件运行程序时,会出现vanilla .net异常框,而不是我编码的那个。
你有什么理由可以想到为什么会这样吗? 最奇怪的是,它在调试模式下运行与自行运行时的行为完全不同。 我正在构建调试 - 而不是发布。
编辑(3月22日至21日):
我只是在这里添加一些小附录,以防你们中的一些人在下面接受的答案的评论中找不到答案: 忘记我说我正在构建调试而不是发布。这没有关系 - 我只是添加它以获取额外信息。重要的是,当我在VS中调试 ging 时,会按预期捕获异常,但在VS外部执行EXE则不会。
正如Cody所说,Application.Run()
有自己的异常处理程序,这就是为什么他们永远不会到达我的主catch
,但我提到我甚至没有在我的任何地方使用Application.Run()
代码...而我的GUI首先使用Form.ShowDialog()
启动。
我已经做了一些实验,并且可以确认Form.ShowDialog()
与Application.Run()
的行为相同,因为异常是在方法本身内处理的。
答案 0 :(得分:6)
这是预期的行为。
您看到的差异是应用程序在附加调试器的情况下运行的结果。从Visual Studio中启动它时,调试器会自动附加(当然,除非您选择“Start Without Debugging”)。这会禁用内置的异常处理程序,该异常处理程序负责向您显示“vanilla”.NET异常对话框。从外部VS启动它不会附加调试器,从而启用内置异常处理。 (请注意,这与在“调试”模式下与“发布”模式编译程序无关。)
有关详细信息,请参阅the accepted answer至this related question。我不相信VB.NET和C#之间的区别在这种情况下是相关的。
正如答案所提到的那样,是一种禁用内置异常处理程序的方法。但在选择之前,我建议您重新考虑您的方法。您可以考虑处理内置的sounds like a bit of a code smell to me,而不是将整个Main
方法包装在AppDomain.UnhandledException
event的try-catch块中。 Jeff Atwood发表了一篇很棒的文章here on Code Project,关于如何使用您自己的用户友好方法替换标准的.NET异常处理。他提出的解决方案变得更加优雅,因为.NET FW的后续版本改进了AppDomain.UnhandledException
事件的处理方式。