我应该多久使用一次 C# 中的 try 和 catch?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/505471/
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 often should I use try and catch in C#?
提问by Justin Tanner
When writing a C# application whose #1 priority is to never crash, how often should I used a try-catch block?
在编写第一个优先级是永不崩溃的 C# 应用程序时,我应该多久使用一次 try-catch 块?
Can I encapsulate all the statements in a method in try-catch blocks?
我可以将方法中的所有语句封装在 try-catch 块中吗?
public void SomeMethod()
{
try
{
// entire contents of the function
// library calls
// function calls
// variable initialization .. etc
}
catch (Exception e)
{
// recover
}
}
What are the downsides to wrapping everything in try-catch blocks?
将所有内容都包装在 try-catch 块中的缺点是什么?
采纳答案by scottm
The only down side is when an exception is actually thrown. There is no overhead for wrapping the code, except for when exceptions occur.
唯一的缺点是实际抛出异常时。包装代码没有开销,除非发生异常。
Also, you don't want to use try/catch for control flow. Consider this (bad code):
此外,您不想使用 try/catch 进行控制流。考虑这个(坏代码):
try {
FileStream fs = File.Open("somefile.txt", FileMode.Open);
} catch (Exception ex) {
MessageBox.Show("The file does not exist. Please select another file");
}
You'll get more performance from some thing like File.Exists. such as:
您将从 File.Exists 之类的东西中获得更高的性能。如:
if(!File.Exists("somefile.txt"))
MessageBox.Show("The file does not exist.")
EDIT: found the MSDN direct quote:
编辑:找到MSDN 直接引用:
Finding and designing away exception-heavy code can result in a decent perf win. Bear in mind that this has nothing to do with try/catch blocks: you only incur the cost when the actual exception is thrown. You can use as many try/catch blocks as you want. Using exceptions gratuitously is where you lose performance. For example, you should stay away from things like using exceptions for control flow.
查找和设计异常繁重的代码可以带来不错的性能胜利。请记住,这与 try/catch 块无关:只有在抛出实际异常时才会产生成本。您可以根据需要使用任意数量的 try/catch 块。无故使用异常会导致性能下降。例如,您应该远离使用异常进行控制流之类的事情。
回答by Matt Briggs
There is performance overhead for try blocks, if you do that your entire function will run slower then it otherwise would. catch (Exception e)
is also a bad idea, if you catch you want to do something useful with what you caught, and if you catch all exceptions it is impossible to know what you should be doing.
try 块有性能开销,如果你这样做,你的整个函数将运行得更慢,否则会。 catch (Exception e)
也是一个坏主意,如果你捕获你想用你捕获的东西做一些有用的事情,如果你捕获所有异常,就不可能知道你应该做什么。
回答by Marc Gravell
Actually, I very rarely use a catch block except for logging purposes. finally
is much more common for me. Most times, lock
or using
do everything I can usefully do (and indeed, that is a finally
also).
实际上,除了日志目的,我很少使用 catch 块。finally
对我来说更常见。大多数时候,lock
或者using
做我能做的一切有用的事情(事实上,那finally
也是)。
Eric Lippert has a blog entry on exceptionsthat may be useful.
回答by CubanX
You can do this, although almost in any given environment you're running in, there's a global exception handler where you can catch and handle even unknown errors.
您可以这样做,尽管几乎在您运行的任何给定环境中,都有一个全局异常处理程序,您可以在其中捕获和处理甚至未知错误。
For web apps, there's the Global.asax, for a console program, just wrap your Main() in a try/catch, for services, there's AppDomain.CurrentDomain.UnhandledException, etc.
对于 Web 应用程序,有 Global.asax,对于控制台程序,只需将 Main() 包装在 try/catch 中,对于服务,有 AppDomain.CurrentDomain.UnhandledException 等。
You should wrap sections where you can predict what the exception might be in more specific blocks, but the global exception handlers should greatly simplify your code and help you out.
您应该在可以预测更具体块中的异常的部分进行包装,但全局异常处理程序应该大大简化您的代码并帮助您解决问题。
回答by David Basarab
You should use them anytime a piece of code can thrown an exception.
您应该在一段代码可能引发异常的任何时候使用它们。
You have to be careful, catching general exceptions is never a good idea. You have to decide which layer you want to handle them.
你必须小心,捕捉一般异常从来都不是一个好主意。您必须决定要处理它们的图层。
Meaning the deeper you are you want to catch very specific excpetion and go more general. In a database catch the SqlException. As you go higher in the stack you catch more exceptions to finally catching the general exception at the very top.
这意味着您想要捕获非常具体的异常并变得更一般。在数据库中捕获 SqlException。随着您在堆栈中的位置越来越高,您会捕获更多异常,最终在最顶部捕获一般异常。
That way you can deal with each exception on a case by case basis. A general exception you aren't going to know what to do with.
这样您就可以根据具体情况处理每个异常。您不知道该怎么处理的一般例外。
回答by cgreeno
Generally IMO it is better to put smaller chunks that are out of your control in a try catch. If you say:
通常,IMO 最好将不受您控制的较小块放在 try catch 中。如果你说:
try
{
//anything that could possibly go wrong
//This kind of thing is only good for Logging IMO and could be done in
//Global.asax
}
How could you possibly know what to do in your catch method cause it could be anything...
你怎么可能知道在你的 catch 方法中做什么,因为它可能是任何东西......
Its much better to go:
最好去:
try
{
//divide user imputs
}
catch(DivideByZeroException)
{
// tell user bad inputs ect....
}
catch (Exception e)
{
//If you choose to throw the exception you should
//***********************
throw;
//VS
throw ex; //Throw ex will restart the stack trace
// recover
}
finally
{
//Clean up resources and continue
}
In which finally is always run
其中 finally 总是运行
回答by Greg Beech
The key to this question is the following line:
这个问题的关键是以下几行:
// recover
To be able to recover, you have to know what and how to recover. And that's assuming it is possible to recover, which quite frequently it isn't.
为了能够恢复,您必须知道恢复什么以及如何恢复。那是假设有可能恢复,但通常情况并非如此。
You should only use the catch
part of try/catch/finally
to swallow an exception when you know how to handle the exception, when you know how to recover from it, and when you're sure you can do so without leaving the application in an inconsistent or invalid state.
只有当您知道如何处理异常、知道如何从异常中恢复并且确定可以这样做而不会使应用程序处于不一致或无效状态时,才应该使用 的catch
部分try/catch/finally
来吞下异常。
If you can do this for all possible exceptions in all method calls in your application then go right ahead, otherwise you might need to re-think your #1 priority (sometimes failing fast is a better options than trying to keep an application alive when something has gone wrong, and having a much harder to debug crash later on).
如果您可以对应用程序中所有方法调用中的所有可能的异常执行此操作,请继续执行此操作,否则您可能需要重新考虑您的 #1 优先级(有时快速失败比在某些情况下尝试使应用程序保持活动状态更好)出了问题,并且以后更难调试崩溃)。
回答by Yes - that Jake.
Our current application has a similar mandate: Never crash. Always back out gracefully. To do this, you have to make sure that every line of code is either enclosed in a try-catch block or only called by code that its exceptions can bubble up into.
我们当前的应用程序有一个类似的任务:永不崩溃。总是优雅地退出。为此,您必须确保每一行代码都包含在 try-catch 块中或仅由其异常可以冒泡的代码调用。
Also, to protect against uncaught exceptions, we attach an UnhandledExceptionEventHandler to AppDomain.CurrentDomain.
此外,为了防止未捕获的异常,我们将 UnhandledExceptionEventHandler 附加到 AppDomain.CurrentDomain。
回答by Frank Schwieterman
You should only catch and stop the exception without rethrowing it if you can meaningfully handle it. Otherwise it is an error and it should propagate up.
如果您可以有意义地处理它,您应该只捕获并停止异常而不重新抛出它。否则它是一个错误,它应该向上传播。
I assume that when they say "this app should never crash" there is an implicit requirement that it behaves correctly. Only stoping exceptions that are meaningfully handled satisfies the behaving correctly requirement.
我假设当他们说“这个应用程序永远不应该崩溃”时,有一个隐含的要求,那就是它的行为是正确的。只有停止有意义地处理的异常才能满足行为正确的要求。
Typically an app will have a single top-level catch block to catch and log unhandled exceptions. These should occur infrequently (and perhaps your requirement can be interpreted to mean these should not happen at all). If you catch and stop exceptions anywhere else in your code, you risk not discovering these problems. If you catch log and stop in lots of other parts of your code, you have a poorly constructed app from the perspective of separation-of-concerns.
通常,应用程序将有一个顶级 catch 块来捕获和记录未处理的异常。这些应该很少发生(也许您的要求可以解释为根本不应该发生)。如果您在代码中的任何其他地方捕获并停止异常,您就有可能无法发现这些问题。如果您在代码的许多其他部分捕获日志并停止,那么从关注点分离的角度来看,您的应用程序构建得很差。
回答by jlembke
This is a big topic. Start herefor some excellent discussion of Exception handling best practices and be prepared for a religious war...
这是一个很大的话题。从这里开始对异常处理最佳实践进行一些精彩的讨论,并为宗教战争做好准备......
Checked vs Unchecked Exceptions
My own opinion is that for the most part you use "try/finally" a lot, but "catch" very little. The problem is that if you attempt to catch and handle Exceptions in the wrong instances, you may inadvertently put your application in a bad state. As a rule, use dev and test to learn where you actually need to handle an exception. Those will be places that you can't check. i.e. you shouldn't really need to handle nullreference or filenotfound because you can proactively check for those. Only exceptions you know may happen, but you can't do anything about. Beyond that, for the sake of your data's state, let it crash.
我自己的观点是,在大多数情况下,您经常使用“try/finally”,而“catch”很少。问题是,如果您尝试在错误的实例中捕获和处理异常,您可能会无意中将应用程序置于错误状态。通常,使用 dev 和 test 来了解您实际需要处理异常的位置。这些将是您无法检查的地方。即你真的不需要处理 nullreference 或 filenotfound 因为你可以主动检查它们。只有您知道的例外可能会发生,但您无能为力。除此之外,为了您的数据状态,让它崩溃。
If you are swallowing exceptions, it generally means you don't understand your program or why you are getting an exception. Catching System.Exception is the poster child of code smells...
如果您吞下了异常,这通常意味着您不了解您的程序或您为什么会遇到异常。捕获 System.Exception 是代码异味的典型代表......