私はコードの例外安全性の改善に取り組んでおり、C#コンストラクトThreadAbortException
でリソースを保護している場合でも、raise によって望ましくないリソース リークが発生する可能性があることに気付きました。using
たとえば、次のコードを考えてみましょう (別のスレッドで実行されている可能性があります)。
using (TextWriter writer = CreateWriter(filename))
{
// do something with the writer.
}
TextWriter CreateWriter(string filename)
{
return new CustomWriter(File.OpenWrite(filename));
}
このコードを実行しているスレッドが異常終了した場合は、 が参照するファイル ハンドルfilename
をすぐに閉じてください。using
コンストラクトの使用を try/finally ブロックに置き換えずにこれを行うことはできますか?
これは、いつでも発生する可能性があるということです。つまりThreadAbortException
、ステートメント間で何が起こっているかに注意を払う必要があります。CreateWriter
try/finally ブロックを使用して例外を防ぐことはできますが、括弧内の式が評価されるまで構造は同じことを行いません。つまり、リターンusing
の直後に例外が発生した場合、ファイル リソースは開いたままになります。CreateWriter
ThreadAbortException
ファイナライザーが最終的にファイルハンドルを解放することは理解していますが、使用されている各場所でキャッチせずにこの問題に対処する決定論的な方法があるかどうか疑問に思っていますCreateWriter
.