如何使用 finally 執行清除程式碼
finally
陳述式的目的是為了確保在必要時會立即清除物件 (通常是含有外部資源的物件),即使擲回例外狀況也一樣。 這類清除的一個例子,是在使用後立即呼叫 FileStream 的 Close,而不等候 Common Language Runtime 回收物件的記憶體,如下所示:
static void CodeWithoutCleanup()
{
FileStream? file = null;
FileInfo fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
範例
為了將上述程式碼變成 try-catch-finally
陳述式,清除程式碼會與工作程式碼分開,如下所示。
static void CodeWithCleanup()
{
FileStream? file = null;
FileInfo? fileInfo = null;
try
{
fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
finally
{
file?.Close();
}
}
因為在 OpenWrite()
呼叫之前,try
區塊內隨時都可能會發生例外狀況,或是 OpenWrite()
呼叫本身可能會失敗,所以在嘗試關閉檔案時不保證檔案處於開啟狀態。 finally
區塊新增檢查,請先確定 FileStream 物件不是null
,再呼叫 Close 方法。 如果沒有 null
檢查,finally
區塊可能會擲回本身的 NullReferenceException,但應盡可能避免在 finally
區塊中擲回例外狀況。
在 finally
區塊中關閉資料庫連接是另一個不錯的選擇。 因為允許連接至資料庫伺服器的連接數目有時候是有限的,所以您應該盡快關閉資料庫連接。 如果在您可以關閉連接之前就擲回例外狀況,則使用 finally
區塊會比等候記憶體回收更適合。