2012-02-15 112 views
49

是否有適合使用try-finally塊而沒有catch塊的情況?使用沒有'catch'塊的'try-finally'塊

+0

在MSDN上,請參閱[try-finally(C#Reference)](https://msdn.microsoft.com/en-us/library/zwc8s4fz%28v=vs.140%29.aspx)。注意這篇文章引用了'try'和'finally'作爲「** try-finally ** *語句*」的組合使用。代碼示例中的代碼爲 – DavidRR 2016-03-24 13:00:19

回答

80

您可以使用它來確保在try內容或異常之後發生某些操作,但是當您不希望使用該異常時。

只是要清楚,這不會隱藏異常。在異常傳播到調用堆棧之前,將運行finally塊。

當您使用using關鍵字時,您也會無意中使用它,因爲它編譯爲try-finally(不是確切的轉換,而是因爲參數的緣故,它足夠接近)。在finally運行

try 
{ 
    TrySomeCodeThatMightException(); 
} 
finally 
{ 
    CleanupEvenOnFailure(); 
} 

代碼是不能保證運行,但它不能保證是相當邊緣的情況下 - 我甚至不記得它。我記得的只是,如果你是那樣的話,那麼運行finally不是最大的問題:-)所以基本上不會出汗。

來自Tobias的更新:finally如果進程被終止將不會運行。從稻田

更新:Conditions when finally does not execute in a .net try..finally block

,最普遍的例子,你可能會看到即使代碼失敗,則配置數據庫連接或外部資源:

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(); 
} 
+2

+1。 – 2012-02-15 10:16:58

+0

有沒有很好的理由來做到這一點?隱藏異常不是很糟糕的做法!? – AnthonyBlake 2012-02-15 10:21:13

+11

@AnthonyBlake異常不隱藏。如果發生異常,它將運行finally,然後將該異常傳播回調用堆棧。 – 2012-02-15 10:22:02

1

你需要一個finally塊,當不管哪個(如果有)異常被捕獲,或者即使沒有被捕獲,你仍然想在塊退出前執行一些代碼。例如,你可能想關閉一個打開的文件。

請參見try-finally

1

的try /最後:當你不希望處理任何異常,但要確保一些行動(S)發生異常是否是由稱爲碼拋出。

5

using相當於try-finally。當您想在finally內部進行一些清理時,您只會使用try-finally,並且不在意這個例外情況。

最好的辦法

try 
{ 
    using(resource) 
    { 
     //Do something here 
    } 
}catch(Exception) 
{ 
    //Handle Error 
} 

這樣做甚至清理由using叫失敗,您的代碼不會失敗。

有些情況下,finally不會被執行。

  • 如果有任何StackOverflowExceptionExecutingEngineException
  • 進程從外部源中被終止。

希望這回答你的疑問。

2

如果您有,例如您在try塊中創建並使用的非託管資源,則可以使用finally塊來確保釋放該資源。儘管try塊中會發生什麼(例外),finally塊將始終執行。

E.g.鎖(x)的說法是真的:

System.Threading.Monitor.Enter(x); 
try { ... } 
finally 
{ 
    System.Threading.Monitor.Exit(x); 
} 

finally塊總是會被調用,以確保排它鎖釋放。

2

很好的解釋使用代碼:

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拋出異常,它將被MyMethod1捕獲。但是,MyMethod2中的代碼需要運行清理代碼,例如在異常傳遞給MyMethod1之前關閉數據庫連接。

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+

+0

這個'清理'的例子可能是saveLogFile(),我經常想把它放在程序的最後,不管是什麼。 – Vincent 2017-10-29 19:51:20

0

下面是我一直(呃..)使用用例:

int? x; //note the nullable type here! 
try 
{ 
    x = int.Parse(someString); 
} 
catch { } //don't care, let it just be null 
1

這是一個情況下,你可能想使用try最後:當你通常會使用一個使用聲明,但不能因爲您正在通過反射調用方法。

這將無法正常工作

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(); 
      } 
0

1.我們可以使用try塊沒有趕上,但是我們應該使用catch /終於, 它們中的任何一個。 2.我們不能只使用try塊。