Overriding the Finalize methodとObject.Finalize documentationで説明されているように、私は答えが「いいえ」であると確信していました。
ただし、FileStream
Reflector をランダムにブラウジングしているときに、ファイナライザーからそのようなメソッドを実際に呼び出すことができることがわかりました。
private SafeFileHandle _handle;
~FileStream()
{
if (this._handle != null)
{
this.Dispose(false);
}
}
protected override void Dispose(bool disposing)
{
try
{
...
}
finally
{
if ((this._handle != null) && !this._handle.IsClosed) // <=== HERE
{
this._handle.Dispose(); // <=== AND HERE
}
[...]
}
}
書かれている正確な方法のためにこれが常に機能するかどうか疑問に思い始めました。したがって、「ファイナライザーからマネージドクラスに触れないでください」は、正当な理由とそれを行うために必要な知識があれば、破ることができるガイドラインにすぎないかどうか右。
もう少し深く掘り下げたところ、「ルール」が破られたときに起こりうる最悪の事態は、アクセスされている管理対象オブジェクトがすでにファイナライズされているか、別のスレッドで並行してファイナライズされている可能性があることがわかりました。したがって、SafeFileHandle のファイナライザーが、その後の Dispose の呼び出しが失敗する原因となるようなことを何もしなかった場合、上記は問題ないはずです...そうですか?
質問: 結局のところ、別のマネージ クラスのメソッドがファイナライザーから確実に呼び出される可能性があるという状況はありますか? 私はいつもこれが間違っていると信じていましたが、このコードはそれが可能であり、そうする十分な理由があることを示唆しています.
おまけ:SafeFileHandle
はファイナライザーから呼び出されていることさえ認識しないことに注意してDispose()
ください。基本クラス にはSafeHandle
、実際には と の 2 つのプライベート メソッドがInternalDispose
ありInternalFinalize
、この場合InternalDispose
は が呼び出されます。これは問題ではありませんか?なぜだめですか?...