1

クラスBの最後のインスタンスがファイナライズされるまで、クラスAのインスタンスが存在するように定義する方法については、100% 明確ではありません。

または、言い換えれば、すべての BがBのファイナライズ内でA のclose&dispose メソッドを呼び出すようにしたいと思います...そして、それはA自体がファイナライズされる前に行われます。

シナリオ:

A. アンマネージド リソース用のマネージド ラッパーがあります。類推のために、Aをファイルシステムと呼びましょう

B. A を参照するマネージド リソースで、A ラッパーを介してアンマネージド リソースを要求したもの。類推のために、B をファイルと呼びましょう。

追加のリクエスト --> using 構文がうまく動作するようにしてください。つまり、dispose を明示的に呼び出しても、アンマネージ リソースは破棄されません。オブジェクトはオブジェクト プールに存在します。オブジェクトプールを離れたときにのみ破棄する必要があります。

class SomeClass() : IDisposable{

    public SomeClass(){}

    public ~SomeClass(){
       // dispose of unmanaged here?
    }

    // Dispose(bool disposing) executes in two distinct scenarios.
    // If disposing equals true, the method has been called directly
    // or indirectly by a user's code. Managed and unmanaged resources
    // can be disposed.
    // If disposing equals false, the method has been called by the
    // runtime from inside the finalizer and you should not reference
    // other objects. Only unmanaged resources can be disposed.
    public void Dispose(bool disposing) {
        if (disposing) {
            // dispose managed
        } else {
            // dispose unmanaged?
        }
    }

    public void Dispose() {
        Dispose(true);
        //GC.SuppressFinalize(this);
    }

}

参考文献:

[1] Finalize メソッドをオーバーライドできない理由

[2] Cシャープ第3版によるCLR。Ch。21. CriticalFinalizerObject。特に pp. 537「マネージド リソースでファイナライズを使用する」

4

1 に答える 1

2

一般に、ファイナライズの順序を制御することはできません。ただし、 CriticalFinalizerObjectを使用して、2 フェーズの順序を制御できます。また、SafeHandle インフラストラクチャと、FileStream がどのようにそれを行うかについても見てください。

それだけでは不十分な場合は、静的クラス メンバー (List または Dictionary など) からオブジェクト参照を作成することにより、有効期間を任意に制御できます。これらの参照を解放した場合にのみ、ファイナライズが発生します。したがって、B への GCHandle が無効になったことに気付いたら、A への参照を作成してクリアします。

于 2012-04-15T17:32:17.483 に答える