方法: finally を使用してクリーンアップ コードを実行する (C# プログラミング ガイド)
finally ステートメントの目的は、例外がスローされた場合でも、オブジェクト (一般に外部リソースを保持しているオブジェクト) に対して必要なクリーンアップを即座に実行できるようにすることです。 次のように、共通言語ランタイムによってオブジェクトがガベージ コレクションされるまで待機する代わりに、オブジェクトを使用した後すぐに FileStream で Close を呼び出すというのも、このようなクリーンアップの一例です。
static void CodeWithoutCleanup()
{
System.IO.FileStream file = null;
System.IO.FileInfo fileInfo = new System.IO.FileInfo("C:\\file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
使用例
上のコードを try-catch-finally ステートメントに変えるには、次のようにクリーンアップ コードを作業コードから分離します。
static void CodeWithCleanup()
{
System.IO.FileStream file = null;
System.IO.FileInfo fileInfo = null;
try
{
fileInfo = new System.IO.FileInfo("C:\\file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
catch(System.UnauthorizedAccessException e)
{
System.Console.WriteLine(e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
}
例外は OpenWrite() 呼び出しの前に try ブロック内でどの時点でも発生する可能性があるため、または OpenWrite() 呼び出し自体が失敗する可能性があるため、ファイルを閉じようとしたときにそのファイルが開いているという保証はありません。 finally ブロックでは、Close メソッドを呼び出す前に、FileStream オブジェクトが null でないことを確認するチェックを行います。 この null チェックを行わないと、finally ブロックから NullReferenceException がスローされる可能性がありますが、finally ブロックにおける例外のスローはできるだけ回避する必要があります。
データベース接続も、finally ブロックで閉じられる対象になります。 データベース サーバーに許容される接続数は限られている場合があるため、データベース接続はできるだけ早く閉じる必要があります。 接続を閉じる前に例外がスローされる場合でも、ガベージ コレクションを待機するより、finally ブロックを使用することをお勧めします。