.net 为什么在 Try ... Catch 中使用 finally
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1158667/
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
Why use Finally in Try ... Catch
提问by awe
I see that the Finallyin Try .. Catchwill always execute after any parts of the execution of the try catch block.
我看到FinallyinTry .. Catch将始终在执行 try catch 块的任何部分之后执行。
Is it any different to just skip the Finallysection and just run it after, outside the try catch block?
跳过该Finally部分并在 try catch 块之外运行它有什么不同吗?
Example 1, Try ... Catch ... Finally ... End Try
示例 1, Try ... Catch ... 最后 ... End Try
Try
'Do something
Catch ex As Exception
'Handle exception
Finally
'Do cleanup
End Try
Example 2, Try ... Catch ... End Try ... Do the finally stuff outside
示例 2, Try ... Catch ... End Try ... 在外面做最后的事情
Try
'Do something
Catch ex As Exception
'Handle exception
End Try
'Do cleanup
回答by kemiller2002
Yes, it is different. Finally will always run (barring program crash). If the function exits inside of the try catch block, or another error is thrown in either the try or the catch, the finally will still execute. You won't get that functionality not using the finally statement.
是的,它是不同的。最后将始终运行(除非程序崩溃)。如果函数在 try catch 块内退出,或者在 try 或 catch 中抛出另一个错误,finally 仍将执行。如果不使用 finally 语句,您将无法获得该功能。
回答by pashute
Code with four radio buttons:
带有四个单选按钮的代码:
- Return in TRY
- Return in CATCH
- Throw in CATCH
Finish CATCH
private void checkFinally() { try { doFinally(); } catch { Console.WriteLine(" Breaking news: a crash occured. "); } } private void doFinally() { Console.WriteLine(" "); Console.Write("Here goes: " + (radioReturnInTry.Checked ? "2. Return in try: " : (radioReturnInCatch.Checked? "3. Retrun in catch: " : (radioThrowInCatch.Checked? "4. Throw in catch: " : "1. Continue in catch: "))) ); try { if (radioReturnInTry.Checked) { Console.Write(" Returning in try. "); return; } Console.Write(" Throwing up in try. "); throw new Exception("check your checkbox."); } catch (Exception ex) { Console.Write(" ...caughtcha! "); if (radioReturnInCatch.Checked) { Console.Write("Returning in catch. "); return; } if (radioThrowInCatch.Checked) { Console.Write(" Throwing up in catch. "); throw new Exception("after caught"); } } finally { Console.Write(" Finally!!"); } Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, // this would never happen (and was marked grey by ReSharper) }
- 以 TRY 返回
- 在 CATCH 中返回
- 投入 CATCH
完成捕捉
private void checkFinally() { try { doFinally(); } catch { Console.WriteLine(" Breaking news: a crash occured. "); } } private void doFinally() { Console.WriteLine(" "); Console.Write("Here goes: " + (radioReturnInTry.Checked ? "2. Return in try: " : (radioReturnInCatch.Checked? "3. Retrun in catch: " : (radioThrowInCatch.Checked? "4. Throw in catch: " : "1. Continue in catch: "))) ); try { if (radioReturnInTry.Checked) { Console.Write(" Returning in try. "); return; } Console.Write(" Throwing up in try. "); throw new Exception("check your checkbox."); } catch (Exception ex) { Console.Write(" ...caughtcha! "); if (radioReturnInCatch.Checked) { Console.Write("Returning in catch. "); return; } if (radioThrowInCatch.Checked) { Console.Write(" Throwing up in catch. "); throw new Exception("after caught"); } } finally { Console.Write(" Finally!!"); } Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, // this would never happen (and was marked grey by ReSharper) }
Output:
输出:
- Here goes: 1. Continue in catch: Throwing up in try. ...caughtcha! Finally!! Done!!!
- Here goes: 2. Return in try: Returning in try. Finally!!
- Here goes: 3. Retrun in catch: Throwing up in try. ...caughtcha! Returning in catch. Finally!!
- Here goes: 4. Throw in catch: Throwing up in try. ...caughtcha! Throwing up in catch. Finally!! Breaking news: a crash occured.
- 这是: 1. 继续抓:在尝试中吐。......抓住了!最后!!完毕!!!
- 这是: 2. 尝试返回: 尝试返回。最后!!
- 这是: 3. 在捕获中返回:在尝试中抛出。......抓住了!捕捞归来。最后!!
- 这是: 4. 投掷:在尝试中投掷。......抓住了!投掷中。最后!!突发新闻:发生崩溃。
To summarize: Finally takes care of two things:
总结:最后处理两件事:
- Of code that returnedin the try or in the catch.
- Or If you had an exception in the try, AND THROW an exception in the catch,
- or, if you had an exception in the try, AND DID NOT CATCH that exception,
- 在try 或 catch中返回的代码。
- 或者如果你在 try 中有异常,并且在 catch 中抛出异常,
- 或者,如果您在 try 中有异常,并且没有捕获该异常,
Finally to summarize "FINALLY": Finallydoes nothing special if you tried,and
最后总结一下“FINALLY”:如果你尝试过,最后没有什么特别的,并且
- DID NOT RETURN,
- and caught any exceptions during the trial, and then
- DID NOT RETURN in the catch either, and
- DID NOT THROW or have code that throws up.
- 没有回来,
- 并在试验期间捕获任何异常,然后
- 也没有返回渔获物,并且
- 没有抛出或有抛出的代码。
And last but not least (finally): If you have an exception in your code that YOU DID NOT CATCH, your code will fly, WITHOUT REACHING THE FINALLY.
最后但并非最不重要的(最后):如果您的代码中有一个您没有捕捉到的异常,您的代码将会飞,而不会到达最终。
Hope this is clear. (Now it is to me...)
希望这很清楚。(现在对我来说……)
Moshe
摩西
回答by rahul
Finally contains code that needs to be evaluated at all conditions [whether or not an exception occurred].
最后包含需要在所有条件下评估的代码[无论是否发生异常]。
There is no way to exit a try block without executing its finally block. If the finally block exists, it always executes. (This statement is true for all intents and purposes. There is a way to exit a try block without executing the finally block. If the code executes a System.exit(0); from within a try block, the application terminates without the finally executing. On the other hand, if you unplug the machine during a try block, the finally will not execute either.)
如果不执行 finally 块,就无法退出 try 块。如果 finally 块存在,它总是执行。(此语句适用于所有意图和目的。有一种方法可以在不执行 finally 块的情况下退出 try 块。如果代码执行 System.exit(0); 从 try 块内,应用程序将在没有 finally 块的情况下终止执行。另一方面,如果你在 try 块期间拔掉机器,finally 也不会执行。)
The main use is for disposing objects. It will be useful when you want to close user defined resources like file , opened resources(db stmts).
主要用途是处理对象。当您要关闭用户定义的资源(如文件、打开的资源(db stmts))时,这将非常有用。
Edit
编辑
Also finally won't be executed after a stackoverflow exception.
在 stackoverflow 异常之后也不会执行 finally。
回答by RichieHindle
The difference is when the code in the tryblock throws an exception that isn't caught by the catchblock.
不同之处在于当try块中的代码抛出未被catch块捕获的异常时。
Normally a catchblock would catch a specific type of exception, and let anything else through. In that case, the finallyblock will still run.
通常,catch块会捕获特定类型的异常,并让其他任何异常通过。在这种情况下,该finally块仍将运行。
The finallyblock will also run if the code in the tryblock returns.
在finally如果在代码块也将运行try块return秒。
回答by scheibk
This is a good idea when dealing with database connections or anytime objects need to be disposed of. Just in case something goes wrong while running queries, you can still close the connection safely. It also helps to clean up code that the block outside the try/catch/finally block is not able to access.
在处理数据库连接或任何需要处理的对象时,这是一个好主意。万一在运行查询时出现问题,您仍然可以安全地关闭连接。它还有助于清理 try/catch/finally 块之外的块无法访问的代码。
回答by Nick Haddad
The Finally block will execute regardless of if the function exits because of an exception. (there are some exceptions to this rule, see this stackoverflow questionfor more info).
无论函数是否因异常退出,Finally 块都会执行。(此规则有一些例外,有关更多信息,请参阅此 stackoverflow 问题)。
For example:
例如:
Try
'Do something
Catch ex As Exception
if 'Some Condition
throw ex
else
'Handle exception
Finally
'Do cleanup
End Try
In this case the Finally block will still be executed even though you may throw an exception out of the function.
在这种情况下,即使您可能会从函数中抛出异常,仍会执行 finally 块。
This is a good practice to get into because it ensures that your cleanup code always executes. Of course using the Resoource Acquisition Is Initializationidiom is a much cleaner way of ensuring that resources get cleaned up, but I'm not versed enough in VB.net to know if this is possible to do.
这是一个很好的实践,因为它可以确保您的清理代码始终执行。当然,使用资源获取是初始化习语是确保资源得到清理的更简洁的方法,但我对 VB.net 不够精通,不知道这是否可行。
回答by fotanus
Finally should be used to everything that needs to be done in order to keep a system consistent. This usually means release resources
最后应该习惯于需要做的一切,以保持系统一致。这通常意味着释放资源
Finally is always executed, no matter what exception was thrown. It should be used to release resources, in the following cases:
无论抛出什么异常,finally 总是被执行。它应该用于释放资源,在以下情况下:
- Finalize a connection
- Close a file handler
- Free memory
- Close a database connection
- 完成连接
- 关闭文件处理程序
- 空闲内存
- 关闭数据库连接
Let me give a complete example. Imagine that that you are sending messages through the network. In pseudo-code:
让我举一个完整的例子。想象一下,您正在通过网络发送消息。在伪代码中:
// With finally | //Without finally
try{ | try{
send_message() | send_message()
} catch(NetworkError){ | } catch(NetworkError){
deal_with_exception() | deal_with_exception()
} finally { | }
finalizes_connection() | finalizes_connection()
} |
The only difference of both codes is when what is hold in the tryblock raises an exception that is not NetworkError, for example, MethodNotFound. In the first case, the method finalizes_connection()will be called, and in the second one, it will not.
两种代码的唯一区别是当try块中的内容引发异常时,NetworkError例如,MethodNotFound。在第一种情况下,该方法finalizes_connection()将被调用,而在第二种情况下,则不会。
A connection is naturally done through more than one program. So what happens in the case of a MethodNotFoundexception to the other program? In the first case, your program will finish the connection and the other program and it will be happy. In the second case, the other program can be waiting for your response forever. What if the other program can only receive one connection per time? You just bugged the other program as well.
一个连接自然是通过多个程序完成的。那么MethodNotFound在其他程序出现异常的情况下会发生什么?在第一种情况下,您的程序将完成连接和另一个程序,它会很高兴。在第二种情况下,另一个程序可能会永远等待您的响应。如果另一个程序每次只能接收一个连接怎么办?你也只是窃听了另一个程序。
This would also apply for a file, for example, that you opened and other programs wouldn't be able to open for reading (in Windows). And for memory, it is never released and now you have a memory leak.
例如,这也适用于您打开而其他程序无法打开以进行读取的文件(在 Windows 中)。而对于内存,它永远不会被释放,现在你有内存泄漏。
回答by Joe
As far as I can remember I have never used a try/catch/finally block in my .NET code.
据我所知,我从未在我的 .NET 代码中使用过 try/catch/finally 块。
In general, catching exceptions in the middle tier is rarely needed. Exceptions are usually propagated to a top-level handler in the presentation tier (and possibly caught and rethrown at a tier boundary so they can be logged).
一般来说,很少需要在中间层捕获异常。异常通常传播到表示层中的顶级处理程序(并且可能在层边界处被捕获并重新抛出,以便它们可以被记录)。
So in the middle tier you will more often see try/finally (or the "using" statement) so that resources are cleaned up. And in try/catch in the top-level handler in the presentation tier.
因此,在中间层,您将更频繁地看到 try/finally(或“使用”语句),以便清理资源。并且在表示层的顶级处理程序中的 try/catch 中。
In the rare cases that I need to both catch an exception and do some cleanup, I would prefer to refactor so that the following:
在极少数情况下,我需要同时捕获异常并进行一些清理,我更愿意进行重构,以便执行以下操作:
try
{
... do something
}
catch
{
... handle exception
}
finally
{
... cleanup
}
becomes:
变成:
try
{
DoSomethingAndCleanup();
}
catch
{
... handle exception
}
...
private void DoSomethingAndCleanup()
{
try
{
... do something
}
finally
{
... cleanup
}
}
IMHO this is much cleaner.
恕我直言,这更干净。
回答by Giovanni Galbo
On top of what everyone else said, semantically I think that they are different.
除了其他人所说的之外,从语义上讲,我认为它们是不同的。
Code in the finally block clearly states that you're doing finalization type tasks for the content contained within the try-catch. I think this makes it clearer to read.
finally 块中的代码清楚地表明您正在为 try-catch 中包含的内容执行终结类型任务。我认为这使阅读更清晰。
回答by adrianbanks
Doing clean up in a finally block is to ensure that it is run. If the catch block doesn't deal with the exception (ie. it just logs it), or even causes another exception, the code in the finally block will still run.
在 finally 块中进行清理是为了确保它运行。如果 catch 块不处理异常(即它只是记录它),或者甚至导致另一个异常,finally 块中的代码仍将运行。

