使用没有“catch”块的“try-finally”块
在没有catch
块的情况下使用try-finally
块是否合适?
您可以使用它来确保在try
内容或exception之后发生某些操作,但是当您不希望使用该exception时。
只是要清楚,这并不隐藏exception。 在exception传播到调用堆栈之前, finally
块将被运行。
当你使用using
关键字时,你也会不经意地使用它,因为它编译成try-finally
(不是一个确切的转换,但是为了参数的缘故,它足够接近)。
try { TrySomeCodeThatMightException(); } finally { CleanupEvenOnFailure(); }
finally
运行的代码不能保证运行,但是不能保证的情况是相当优越的 – 我甚至不记得它。 我记得的只是,如果你是那样的话,那么运行finally
不是你最大的问题的机会是非常好的:-)所以基本上不会出汗。
Tobias更新:如果进程被finally
将不会运行。
从Paddy更新: 最后不会在.net中执行的条件try..finally block
即使代码失败,您可能会看到的最stream行的示例是丢弃数据库连接或外部资源:
using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-) { // Do stuff. }
编译成如下所示的内容:
SqlConnection conn; try { conn = new SqlConnection(""); // Do stuff. } finally { if (conn != null) conn.Dispose(); }
using
相当于try-finally
。 你最终只会在finally
做一些清理的时候使用try-finally
而不关心exception。
最好的办法是
try { using(resource) { //Do something here } }catch(Exception) { //Handle Error }
这样做甚至通过using
调用清理失败,您的代码将不会失败。
finally
有一些条件不会被执行。
- 如果有任何
StackOverflowException
或ExecutingEngineException
。 - 进程从外部源中被杀死。
希望这回答你的疑问。
如果你有,例如你在try块中创build和使用的非托pipe资源,你可以使用finally块来确保你释放资源。 尽pipe在try块中发生了什么(例如exception),finally块总是会被执行的。
例如lock(x)语句实际上是:
System.Threading.Monitor.Enter(x); try { ... } finally { System.Threading.Monitor.Exit(x); }
finally块总是会被调用来确保独占锁被释放。
良好的解释使用代码:
void MyMethod1() { try { MyMethod2(); MyMethod3(); } catch(Exception e) { //do something with the exception } } void MyMethod2() { try { //perform actions that need cleaning up } finally { //clean up } } void MyMethod3() { //do something }
如果MyMethod2或MyMethod3引发exception,它将被MyMethod1捕获。 但是,MyMethod2中的代码需要在exception传递给MyMethod1之前运行清理代码,例如closures数据库连接。
你需要一个finally块,当无论哪个(如果有)exception被捕获,或者即使没有被捕获,你仍然想在块退出之前执行一些代码。 例如,你可能想要closures一个打开的文件。
另请参阅try-finally
尝试/最后:当你不想处理任何exception,但是想要确保某些动作发生时,不pipe是否有被调用的代码抛出exception。
看看下面的链接: https : //softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause
这取决于应用程序的体系结构以及在块中执行的操作。
这里有一种情况,你可能最终想要使用try:当你通常使用using语句,但不能,因为你正在通过reflection来调用一个方法。
这是行不通的
using (objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO"))) { }
反而使用
object objMsg = null; try { objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO")); strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg, new object[] { vxmlRequest.OuterXml }); } finally { if (objMsg!=null) ((IDisposable)objMsg).Dispose(); }
我不知道任何有关C#的知识,但是看起来你可以用try-finally来做任何事情,你可以更好地使用using语句 。 由于其RAII, C ++甚至没有最终的结果 。
这是一个用例,我总是(嗯..)使用:
int? x; //note the nullable type here! try { x = int.Parse(someString); } catch { } //don't care, let it just be null
1.我们可以使用try块而没有捕获,但我们应该使用catch / finally,其中任何一个。 2.我们不能只使用try块。