C#异常只在调试时被捕获? [英] C# Exceptions only caught when debugging?

查看:111
本文介绍了C#异常只在调试时被捕获?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

发布模式下的异常处理问题


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



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



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



现在,调试时工作正常(F5)。如果我在主线程中的程序中触发异常 ,如果没有尝试/ catch,那么异常会一直返回到Main()并显示自定义窗口。



(所有其他例外,我已经考虑并妥善处理)。



当我简单地运行程序通过运行.exe文件,vanilla .net异常框出现,而不是我编码的。



有什么理由可以想到为什么会发生?
最奇怪的是,在调试模式下运行而不是自己运行时,它的行为有很大的不同。
我正在建立调试 - 而不是发布。



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



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


$ b $如Cody所说,对于例外, Application.Run()有自己的异常处理程序,这就是为什么他们永远不会访问我的主要 catch ,但是我提到我甚至没有在我的代码中的任何地方使用 Application.Run(),而是首先使用 Form.ShowDialog()



我已经做了一些实验,可以确认 Form.ShowDialog ()的行为与 Application.Run()相同,因为该异常在方法本身中处理。

解决方案

这是预期的行为。



应用程序的结果是随着调试器的运行而运行。当您从Visual Studio中启动它时,调试器将自动附加(除非您选择启动不调试)。这将禁用内置异常处理程序,这是一个负责显示vanilla.NET异常对话框的异常处理程序。从外部启动VS不附加调试器,使内置的异常处理能够启用。 (请注意,这与在调试模式与发布模式下编译程序无关。)



请参阅接受的答案这个相关的问题了解更多信息。我不相信VB.NET和C#之间的区别在这种情况下是相关的。



正如该回答提到的那样,禁用内置的异常处理程序。但在选择这样做之前,我建议您重新考虑您的方法。而不是在try-catch块中包装整个 Main 方法,而 AppDomain.UnhandledException 事件。 Jeff Atwood发表了一篇伟大的文章这里的代码项目,关于如何更换标准.NET异常处理与您自己的更方便用户的方法。他提出的解决方案已经变得更加优雅,因为.NET FW的更高版本已经改进了如何处理 AppDomain.UnhandledException 事件。


Possible Duplicate:
Exception handling problem in release mode

I suspect there is a perfectly simple explanation for this, but I can't seem to find it.

When my WinForms C# 4.0 application loads itself in the Program.cs file, the entire Main() function has inside it a try/catch statement.

I have written a little exception wrapper which behaves quite similarly to the vanilla .net "uncaught exception" box, except it provides a bit more information, allows the exception tree to be saved (serialised), and it allows the user to submit the error report directly to me.

Now, it works fine while debugging (F5). If I trigger an exception anywhere in the program which is in the main thread, if there is not try/catch then the exception fires its way all the way back to Main() and shows the custom window.

(All other exceptions I have accounted for and are handled appropriately).

When I run the program simply by running the .exe file, the vanilla .net exception box comes up, not the one I have coded.

Is there any reason you can think of why this would happen? The strangest thing is that it behaves quite differently when running in debug mode vs running on its own. I am building as debug - not release.

Edit (22-March-11):

I'm just adding a little addendum here, in case some of you can't find the answer hidden in the comments for the accepted answer below: Forget that I said I was building as debug instead of release. That is of no relevance - I just added it for extra info. What is important is that when I'm debugging in VS the exceptions are caught as expected, but when executing my EXE outside VS they aren't.

As Cody said, Application.Run() has its own handler for exceptions which is why they never get to my main catch, however I mentioned that I am not even using Application.Run() anywhere in my code... instead my GUI is first launched with Form.ShowDialog().

I have done some experimentation, and can confirm that Form.ShowDialog() behaves the same was as Application.Run() in that exceptions are handled within the method itself.

解决方案

This is the expected behavior.

The difference you see is a result of the application being run with the debugger attached. When you launch it from within Visual Studio, the debugger is automatically attached (unless, of course, you choose to "Start Without Debugging"). That disables the built-in exception handler, which is the one responsible for showing you the "vanilla" .NET exception dialog. Launching it from outside VS doesn't attach the debugger, leaving the built-in exception handling enabled. (Note that this has nothing to do with compiling your program in "Debug" mode versus "Release" mode.)

See the accepted answer to this related question for more information. I do not believe the difference between VB.NET and C# is relevant in this case.

As that answer mentions, there is a way to disable the built-in exception handler. But before choosing to do so, I recommend reconsidering your approach. Rather than wrapping your entire Main method in a try-catch block, which sounds like a bit of a code smell to me, you might consider handling the built-in AppDomain.UnhandledException event. Jeff Atwood posted a great article here on Code Project about how to replace the standard .NET exception handling with your own more user-friendly method. The solution he proposes has become only that much more elegant as later versions of the .NET FW have improved how the AppDomain.UnhandledException event is handled.

这篇关于C#异常只在调试时被捕获?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆