簡體   English   中英

使用沒有“catch”塊的“try-finally”塊

[英]Use a 'try-finally' block without a 'catch' block

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

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

需要明確的是,這並沒有隱藏異常。 finally塊在異常向上傳播到調用堆棧之前運行。

當您使用using關鍵字時,您也會無意中使用它,因為它會編譯成try-finally (不是精確的轉換,但為了參數,它已經足夠接近了)。

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

finally中運行的代碼不能保證運行,但是不能保證的情況是相當邊緣的——我什至不記得了。 我只記得,如果你在那種情況下,很有可能不運行finally不是你最大的問題:-) 所以基本上不要出汗。

來自 Tobias 的更新:如果進程被殺死, finally將不會運行。

來自 Paddy 的更新: 最終不在 .net try..finally 塊中執行時的條件

即使代碼失敗,您可能會看到最普遍的示例是處理數據庫連接或外部資源:

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

使用代碼很好的解釋:

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+

using相當於try-finally 當您想在finally內部進行一些清理並且不關心異常時,您只會使用try-finally

最好的方法

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

這樣做即使using調用的清理失敗,您的代碼也不會失敗。

有一些條件finally不會被執行。

  • 如果有任何StackOverflowExceptionExecutingEngineException
  • 進程被外部源殺死。

例如,如果您有一個在 try 塊中創建和使用的非托管資源,則可以使用 finally 塊來確保釋放該資源。 盡管 try 塊中發生了什么(例如異常),finally 塊將始終被執行。

例如 lock(x) 語句實際上是:

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

finally 塊將始終被調用以確保釋放排他鎖。

這是您可能想要使用 try finally 的情況:當您通常使用 using 語句,但由於您通過反射調用方法而不能使用時。

這行不通

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

您需要一個 finally 塊,當無論捕獲到哪些(如果有)異常,或者即使沒有捕獲到任何異常,您仍然希望在塊退出之前執行一些代碼。 例如,您可能想要關閉一個打開的文件。

另請參閱

try/finally:當您不想處理任何異常但想確保某些操作發生時,無論調用代碼是否拋出異常。

我對 C# 一無所知,但似乎你可以用 try-finally 做的任何事情,你都可以用using 語句更優雅地做。 由於其 RAII , C++ 甚至沒有 finally 。

這是一個我總是(嗯......)使用的用例:

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

1.我們可以使用try塊而不使用catch,但我們應該使用catch/finally,其中任何一個。 2.我們不能只使用try塊。

查看以下鏈接: https ://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause

這取決於您的應用程序的體系結構和您在塊中執行的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM