C# 如何捕获 .NET 应用程序中的所有异常/崩溃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/82483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to catch ALL exceptions/crashes in a .NET app
提问by DougN
Possible Duplicate:
.NET - What's the best way to implement a “catch all exceptions handler”
I have a .NET console app app that is crashing and displaying a message to the user.
All of my code is in a try{<code>} catch(Exception e){<stuff>}
block, but still errors are occasionally displayed.
我有一个 .NET 控制台应用程序崩溃并向用户显示一条消息。我的所有代码都在一个try{<code>} catch(Exception e){<stuff>}
块中,但偶尔仍会显示错误。
In a Win32 app, you can capture all possible exceptions/crashes by installing various exception handlers:
在 Win32 应用程序中,您可以通过安装各种异常处理程序来捕获所有可能的异常/崩溃:
/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler
What is the equivalent in the .NET world so I can handle/log/quiet all possible error cases?
.NET 世界中的等价物是什么,以便我可以处理/记录/安静所有可能的错误情况?
采纳答案by Dario Solera
Contrary to what some others have posted, there's nothing wrong catching all exceptions. The important thing is to handle them all appropriately. If you have a stack overflow or out of memory condition, the app should shut down for them. Also, keep in mind that OOM conditions can prevent your exception handler from running correctly. For example, if your exception handler displays a dialog with the exception message, if you're out of memory, there may not be enough left for the dialog display. Best to log it and shut down immediately.
与其他人发布的内容相反,捕获所有异常并没有错。重要的是要适当地处理它们。如果您遇到堆栈溢出或内存不足的情况,应用程序应该为它们关闭。另外,请记住,OOM 条件会阻止您的异常处理程序正确运行。例如,如果您的异常处理程序显示一个带有异常消息的对话框,如果您的内存不足,则可能没有足够的空间用于对话框显示。最好记录下来并立即关闭。
As others mentioned, there are the UnhandledException and ThreadException events that you can handle to collection exceptions that might otherwise get missed. Then simply throw an exception handler around your main loop (assuming a winforms app).
正如其他人提到的,您可以处理 UnhandledException 和 ThreadException 事件来处理可能会错过的集合异常。然后简单地在你的主循环周围抛出一个异常处理程序(假设一个 winforms 应用程序)。
Also, you should be aware that OutOfMemoryExceptions aren't always thrown for out of memory conditions. An OOM condition can trigger all sorts of exceptions, in your code, or in the framework, that don't necessarily have anything to do with the fact that the real underlying condition is out of memory. I've frequently seen InvalidOperationException or ArgumentException when the underlying cause is actually out of memory.
此外,您应该知道 OutOfMemoryExceptions 并不总是因内存不足而引发。OOM 条件可以在您的代码或框架中触发各种异常,这些异常不一定与真正的底层条件内存不足这一事实有关。当根本原因实际上是内存不足时,我经常看到 InvalidOperationException 或 ArgumentException。
回答by Juanma
You can add an event handler to AppDomain.UnhandledException event, and it'll be called when a exception is thrown and not caught.
您可以为 AppDomain.UnhandledException 事件添加一个事件处理程序,它会在抛出异常但未被捕获时调用。
回答by Mendelt
You can use the AppDomain.CurrentDomain.UnhandledException to get an event.
您可以使用 AppDomain.CurrentDomain.UnhandledException 来获取事件。
回答by Drejc
The Global.asaxclass is your last line of defense. Look at:
在Global.asax中类是你的最后一道防线。看着:
protected void Application_Error(Object sender, EventArgs e)
method
方法
回答by petr k.
You may also go with Application.ThreadException Event.
您也可以使用 Application.ThreadException 事件。
Once I was developing a .NET app running inside a COM based application; this event was the very useful, as AppDomain.CurrentDomain.UnhandledException didn't work in this case.
有一次我正在开发一个在基于 COM 的应用程序中运行的 .NET 应用程序;这个事件非常有用,因为 AppDomain.CurrentDomain.UnhandledException 在这种情况下不起作用。
回答by hangy
I think you should rather not even catch all Exception but better let them be shown to the user. The reason for this is that you should only catch Exceptions which you can actually handle. If you run into some Exception which causes the program to stop but still catch it, this might cause much more severe problems. Also read FAQ: Why does FxCop warn against catch(Exception)?.
我认为您甚至不应该捕获所有异常,而是最好让它们显示给用户。这样做的原因是您应该只捕获您可以实际处理的异常。如果您遇到一些导致程序停止但仍然捕获它的异常,这可能会导致更严重的问题。另请阅读常见问题解答:为什么 FxCop 对 catch(Exception) 发出警告?.
回答by Peli
Be aware that some exception are dangerous to catch - or mostly uncatchable,
请注意,捕获某些异常是危险的 - 或者几乎无法捕获,
- OutOfMemoryException: anything you do in the catch handler might allocate memory (in the managed or unmanaged side of the CLR) and thus trigger another OOM
- StackOverflowException: depending whether the CLR detected it sufficiently early, you might get notified. Worst case scenario, it simply kills the process.
- OutOfMemoryException:您在 catch 处理程序中所做的任何事情都可能分配内存(在 CLR 的托管或非托管端),从而触发另一个 OOM
- StackOverflowException:取决于 CLR 是否足够早地检测到它,您可能会收到通知。最坏的情况是,它只会终止进程。
回答by Johnny Bravado
Be aware that catching these unhandled exceptions can change the security requirements of your application. Your application may stop running correctly under certain contexts (when run from a network share, etc.). Be sure to test thoroughly.
请注意,捕获这些未处理的异常可能会更改应用程序的安全要求。在某些情况下(从网络共享等运行时),您的应用程序可能会停止正确运行。一定要彻底测试。
回答by Ricardo Amores
This article in codeproject by our host Jeff Atwoodis what you need. Includes the code to catch unhandled exceptions and best pratices for showing information about the crash to the user.
我们的主持人 Jeff Atwood 在 codeproject 中的这篇文章正是您所需要的。包括用于捕获未处理异常的代码和用于向用户显示有关崩溃的信息的最佳实践。
回答by Dario Solera
Although catching allexceptions without the plan to properly handle them is surely a bad practice, I think that an application should fail in some graceful way. A crash should not scare the user to death, and at least it should display a description of the error, some information to report to the tech support stuff, and ideally a button to close the application and restart it. In an ideal world, the application should be able to dump on disk the user data, and then try to recover it (but I see that this is asking too much).
尽管在没有计划正确处理它们的情况下捕获所有异常肯定是一种不好的做法,但我认为应用程序应该以某种优雅的方式失败。崩溃不应该把用户吓死,至少它应该显示错误描述、一些向技术支持人员报告的信息,最好是一个关闭应用程序并重新启动它的按钮。在理想的世界中,应用程序应该能够将用户数据转储到磁盘上,然后尝试恢复它(但我发现这要求太多了)。
Anyway, I usually use:
无论如何,我通常使用:
AppDomain.CurrentDomain.UnhandledException