1

ファイナライザーでいくつかの管理対象リソースをクリーンアップする必要があるとします。または、少なくともクリーンアップが必要なスレッドセーフな方法でどこかに記録する必要があるとします。私が理解していることから、ファイナライザーでロックを取得することは厳密に禁じられていますが、Interlocked クラスはどうですか? これは安全で、デッドロックは発生しませんか?

static int deadentries;
~Item() { Interlocked.Increment(ref deadentries); }
public static T Get(int id, Action<T> init) {
    T ret;
    WeakReference<T> tref;
    if (cache.TryGetValue(id, out tref)) {
        if (tref.TryGetTarget(out ret)) return ret;
        else Interlocked.Decrement(ref deadentries);
    }
    if (deadentries * 2 > cache.Count) {
        // etc. etc.

また、すべてのファイナライザーが 1 つのスレッドで実行されているようですが、これは保証された動作ですか、それとも単なる実装の詳細ですか? そして、それが単なる詳細である場合、ロックが他のどこにも取得されないという条件で、ファイナライザー内でロックを取得しても (たとえば、ロックのないキューにジョブをプッシュするために)、これは問題ありませんか?

4

1 に答える 1

1

1 つのスレッドで実行されるファイナライザーは、実装の詳細です (これは、MS が支持する非常に厳格な互換性基準に違反するため、変更される可能性はほとんどありません。依拠することはできません)。

ロックは実際にはファイナライザーで問題ありません。これらはパフォーマンスや正確性の問題になる可能性がありますが、ファイナライザーの一部として実行されるためではありません。これらはロックの一般的なプロパティです。Interlocked クラスも使用できます。

ファイナライザーは任意の順序で実行でき、場合によっては同時に実行できることに注意してください。また、逆依存順序ではなく、ランダムな順序です。

于 2013-03-14T11:48:44.693 に答える