(偽)廃棄が予定されていない場合あなたのクラスもそれから派生したクラスもC#スタイルの "デストラクタ"を含んでいてもFinalizeを上書きしてはならないという非常に良い兆候であり、 "disposing"引数はダンプとみなされます。 protectedパブリックメソッドと異なるシグネチャを破棄します。
親クラスがこのような動作を期待していないときにデストラクタを実装するか、派生クラスでFinalizeをオーバーライドすると、Heisenbugが生成されることに注意してください。とりわけ、GCは、クラスのフィールドで参照されるエンティティが使用されている間でも、クラスオブジェクトが放棄され、ファイナライザ/デストラクタをトリガすることを決定することがあります。たとえば、静的クラスを想定usbThingie
は、整数のハンドルを使用してUSBコントローラを操作して、ラッパークラスusbWrapper
のような何かを行います。それは前のsendData()呼び出しはusbWrapper
のインスタンスに行わ最後のものである場合
UInt32 myHandle;
void sendData(Byte data[])
{
UsbThingie.send(myHandle, data[0], data.Length);
}
を放棄された場合、一度UsbThingie.send()が呼び出されると、たとえそれが返される前であっても、usbWrapper
への参照は存在しないので、ガーベジコレクタはファイナライザを安全にトリガすることができます。ファイナライザがmyHandle
で示されたチャネルを閉じることを試みると、発生していた伝送が中断する可能性があります。 usbThingieがスレッドセーフでない場合、何が起きるかは分かりません。
ロックが非常に長く保持されない場合でも、ファイナライザはロック取得をブロックするべきではありません。何かがロックを不適切に保持すると、他のファイナライザが実行されなくなる可能性があります。 – supercat
@supercatこの例では、コールがファイナライザ内でブロックすることは不可能です。 '_mutex'は、処分目的でのみ使用するべきです。一般的にあなたは正しいですが、この場合、あなたのポイントはすべきではありません。 –
@supercat私の前のコメントが間違っている状況を考えました:別のインスタンスのファイナライズ中に、それがアプリケーションに別のルートを持つように、 'ComplexCleanupBase'のインスタンスを元気に戻す場合、mutexで競合する可能性がありますしかし、これは本当に*できないはずです。回答はすべて更新されました。 –