2012-06-26 115 views
3

我有一些代碼,看起來像這樣:如果catch塊包含continue語句,何時執行finally塊?

foreach(var obj in collection) 
{ 
    try 
    { 
     // WriteToFile returns the name of the written file 
     string filename = WriteToFile(obj); 
     SendFileToExternalAPI(filename); 
    } 
    catch (ArbitraryType1Exception e) 
    { 
     LogError(e); 
     continue; 
    } 
    ... 
    catch (ArbitaryTypeNException e) 
    { 
     LogError(e); 
     continue; 
    } 
    finally 
    { 
     try 
     { 
     File.Delete(filename); 
     } 
     catch (Exception e) 
     { 
     LogError(e); 
     } 
    } 
} 

的目標是嘗試寫出一個臨時文件的集合中的每個對象,試圖加載該文件到其想要的文件名外部API,並然後在完成後清理臨時文件。如果將文件寫入磁盤或將其加載到外部API時發生錯誤,我只想記錄錯誤並轉到下一個對象;我不能要求用戶做什麼。

當catch處理程序中有繼續語句時,我對finally塊的時序如何工作有點不確定。無論是否在try塊中拋出異常,這段代碼是否會(試圖)刪除正確的文件?或者,在finally語句塊運行之前catch語句中的continue是否會生效?

回答

10

把它看成是一個try /終於與捕捉表情可選塊。代碼中的繼續語句會將執行堆棧彈出捕獲程序,該程序會在允許循環繼續之前將執行置於finally塊中。任何時候有try/finally塊,最後都會被執行。

+0

我已經接受這個解決方案,因爲它包含*關於continue語句執行finally代碼塊時*的最清晰描述。 – Hydrargyrum

8

無論是否拋出異常,您的finally塊都將被執行。所以你的finally塊總是會被執行的。

6

finally將作爲try完成之前的最後一步執行。因此它會在正確的時間發生。爲便於概念化,請考慮如果將所有continue語句替換爲return - finally仍將執行,會發生什麼情況。

6

C# Language Specification

8.9.2 continue語句

...

continue語句不能退出finally塊(第8.10節)。當在finally塊內發生一個 continue語句時,continue語句的目標必須位於finally塊中;否則會發生編譯時錯誤 。

continue語句的執行過程如下:

·如果繼續語句退出最後相關聯的塊與 一個或多個try塊,則控制最初轉移到 終於最裏面的try語句的塊。當和如果控制 到達finally塊的結束點時,控制轉移到下一個包含try語句的finally塊的 。重複該過程 ,直到已經執行了所有介入的嘗試語句 的最終塊。

...

相關問題