C#exception仅在调试时被捕获?

可能重复:
发布模式下的exception处理问题

我怀疑对此有一个非常简单的解释,但我似乎无法找到它。

当我的WinForms C#4.0应用程序在Program.cs文件中加载自身时,整个Main()函数内部都有一个try / catch语句。

我编写了一个小exception包装器,其行为与vanilla .net“未捕获exception”框非常相似,除了它提供了更多信息,允许保存(序列化)exception树,并允许用户提交错误直接向我汇报。

现在,它在调试时工作正常(F5)。 如果我在主线程中的程序中的任何地方触发exception,如果没有try / catch,则exception会一直触发到Main()并显示自定义窗口。

(我已经考虑过的所有其他例外情况并得到妥善处理)。

当我只运行.exe文件运行程序时,会出现vanilla .netexception框,而不是我编码的那个。

有什么理由可以想到为什么会发生这种情况? 最奇怪的是,它在调试模式下运行与自行运行时的行为完全不同。 我正在构建调试 – 而不是发布。

编辑(3月22日至11日):

我只是在这里添加一个小附录,以防你们中的一些人在下面接受的答案的评论中找不到答案:忘记我说我正在构建调试而不是发布。 这没有关系 – 我只是添加它以获取额外信息。 重要的是,当我在VS中调试ging时,exception会按预期被捕获,但是当在VS外部执行我的EXE时,它们不是。

正如Cody所说, Application.Run()有自己的exception处理程序,这就是为什么它们永远不会到达我的主要catch ,但是我提到我甚至没有在我的代码中的任何地方使用Application.Run()而是我的GUI首先使用Form.ShowDialog()启动。

我已经做了一些实验,并且可以确认Form.ShowDialog()Application.Run()行为相同,因为exception是在方法本身内处理的。

这是预期的行为。

您看到的差异是应用程序在附加调试器的情况下运行的结果。 从Visual Studio中启动它时,会自动附加调试器(当然,除非您选择“Start Without Debugging”)。 这会禁用内置的exception处理程序,该处理程序负责向您显示“vanilla”.NETexception对话框。 从外部VS启动它不会附加调试器,从而启用内置exception处理。 (请注意,这与在“调试”模式下与“发布”模式编译程序无关。)

有关详细信息,请参阅此相关问题 的已接受答案 。 我不相信VB.NET和C#之间的区别在这种情况下是相关的。

正如答案所提到的,有一种方法可以禁用内置exception处理程序。 但在选择之前,我建议您重新考虑您的方法。 您可以考虑处理内置的AppDomain.UnhandledException事件 ,而不是将整个Main方法包装在try-catch块中,这听起来像是一些代码味道 。 Jeff Atwood 在Code Project上发表了一篇很棒的文章,介绍了如何使用您自己的用户友好方法替换标准的.NETexception处理。 他提出的解决方案变得更加优雅,因为.NET FW的更高版本改进了AppDomain.UnhandledException事件的处理方式。