![](/img/trans.png)
[英]What's the use of a finally block preceded by a catch-all catch block, in C#?
[英]In .NET, what if something fails in the catch block, will finally always get called?
在 try/catch/finally 塊中,例如:
try
{
}
catch()
{
// code fails here
}
finally
{
}
那么如果catch塊中有異常,最終總是會被調用嗎?
如果沒有 finally,catch 塊之后的代碼會運行嗎?
假設進程不會突然終止(當然也不會掛起),finally 塊將始終被執行。
如果沒有 finally 塊,catch 塊中的異常將被拋出堆棧。 請注意,最初導致 catch 塊執行的原始異常將被有效地丟失。
堆棧溢出異常
正如 Jared 所指出的,堆棧溢出將導致 finally 塊不被執行。 我相信這會突然終止程序,但我可能是錯的。 這是示例代碼:
using System;
public class Test
{
static void Main()
{
// Give the stack something to munch on
int x = 10;
try
{
Main();
Console.WriteLine(x);
}
finally
{
Console.WriteLine("Finally");
}
}
}
結果:
進程因 StackOverflowException 而終止。
finally 塊將始終被執行。 如果您排除 finally 塊,並且在 catch 塊內發生異常,則 catch 塊之后不會執行任何代碼,因為本質上您的 catch 塊將失敗並自身生成未處理的異常。
是的,finally 將永遠運行
不,catch 塊之后的代碼將不會運行。
即使使用 finally 塊,finally 塊之后的任何代碼都不會運行。
如果 catch 塊中有異常,finally 會執行,但是會拋出一個新的異常。 發生異常的 catch 塊不會捕獲異常,它會繼續向上堆棧。
經驗教訓:如果你能幫助它,不要在 catch 塊中做可以拋出的東西; 如果必須,請嵌套一個 try/catch 塊。
try
{
}
catch()
{
try
{
// code fails here
}
catch
{
// handle that. Or not.
}
}
finally
{
}
finally 塊將始終被執行。 來自MSDN :
finally 塊對於清理在 try 塊中分配的任何資源以及運行任何必須執行的代碼(即使存在異常)也很有用。 不管 try 塊如何退出,控制總是傳遞給 finally 塊。
catch 用於處理語句塊中發生的異常,而 finally 用於保證語句塊的執行,而不管前面的 try 塊如何退出。
順便說一句,這是您可以通過編寫一些代碼、編譯它並查看執行它時發生的情況來輕松測試自己的問題類型。
class Program {
static void Main(string[] args) {
try {
Console.WriteLine("Trying!");
throw new Exception();
}
catch (Exception e) {
Console.WriteLine("Catching {0}!", e.Message);
throw new Exception();
}
finally {
Console.WriteLine("Finally!");
}
}
}
這輸出:
Trying!
Catching Exception of type 'System.Exception' was thrown.!
Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\My
Documents\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15
Finally!
Press any key to continue. . .
只是想添加我知道的不允許 finally 和任何其他代碼塊執行的情況:
如果 catch 塊中發生異常,finally 中的所有代碼仍然會被執行。 如果堆棧中有更高的異常處理程序(例如此函數的調用者),它將捕獲此異常。 否則會導致未處理的異常並關閉您的應用程序。
catch 塊中異常點之后的代碼不會被調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.