8

さまざまなクラスのインスタンスを追跡する方法が必要です。それらのクラスは、追跡されていることを認識していません。基本的に、インスタンスを作成して別のスレッドに渡すクラスファクトリがあります。そのスレッドが完了してインスタンスをアンロードしたら、その通知を受け取る必要があります。これにより、参照カウントを実行して、すべてのインスタンスがなくなったときにクラスファクトリを終了できます。

課題は、ソースコードを制御していないため、ロードするクラスを変更できないことです。

作成したインスタンスの追跡は簡単です。作成するときに、それらをある種のコレクションに入れることができます。彼らの破壊を追跡することは私に問題を引き起こしています。ソースコードを変更できれば、各クラスにイベントを追加し、インスタンスを作成するときに、イベントにフックして通知として使用します。しかし、それはできません。

だから、問題はこれです:オブジェクトインスタンスを監視し、それがいつ破壊されているかを検出する卑劣な方法はありますか?

4

4 に答える 4

11

オブジェクトを作成しているので、実際のインスタンスの代わりにデコレータを返すことができるようです。

デコレータパターンを使用することで、返されたオブジェクトを独自の装飾されたAPIで「ラップ」することができます。装飾は、破壊通知を提供するIDisposable実装を提供する可能性があります。

于 2010-07-16T18:37:48.073 に答える
5

アクティブな通知を受け取る方法はありませんがWeakReference、オブジェクトを保持し、定期的にオブジェクトが死んでいないかどうかを確認することができます。

編集:私はリードの答えが私のものよりも好きです!

于 2010-07-16T18:38:36.843 に答える
2

作成したインスタンスへの参照のリストを保持している場合、それらはガベージコレクションされないため、破棄されることはありません...

代わりに、Guidのリストを保持するリポジトリを作成し、インスタンスごとに新しいGuidを作成してから、代わりにそれをリストに追加できます(FactoryRepositoryなど)。このように、Guidは参照型ではなく構造体であるため、ガベージコレクションの参照の問題は発生しません。次に、各クラスから継承して、破棄時に通知できるタイプを作成できます。元のクラスのコードを変更できないため、これらのクラスのコンシューマーも変更できないと想定しています。したがって、タイプに互換性がないため、(インターフェイスを介した)デコレーターパターンのようなものが出ています。

非常に単純化された例:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

    public OriginalClassDestroyNotifier(Guid instanceId)
    {
        _instanceId = instanceId;
    }

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}
于 2010-07-16T18:46:55.027 に答える
1

オブジェクトの破壊を制御するのはどうですか。

public void Destroy(T obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");
    if (!_living.Contains(obj))
        throw new ArgumentException("Where did this obj come from?");

    using (obj as IDisposable)
    {

    }

    _living.Remove(obj); // List?
}
于 2010-07-16T18:34:37.287 に答える