Получить уведомление об удалении / уничтожении объекта - PullRequest
8 голосов
/ 16 июля 2010

Мне нужен способ отследить экземпляры различных классов, чтобы эти классы не знали, что они отслеживаются.По сути, у меня есть фабрика классов, которая создает экземпляры и передает их другому потоку.Как только этот поток завершает и выгружает экземпляр, мне нужно получить уведомление об этом, чтобы я мог выполнять подсчет ссылок и выходить из фабрики классов, когда все экземпляры исчезли.

Проблема в том, что я не могу изменитьлюбой из классов, которые я буду загружать, потому что я не контролирую их исходный код.

Отслеживать созданные мной экземпляры просто, я могу просто поместить их в какую-то коллекцию по мере их создания.Отслеживание их уничтожения вызывает у меня проблемы.Если бы я мог изменить исходный код, я бы добавил событие к каждому классу, и когда я создаю экземпляр, я бы подключился к событию и использовал его в качестве своего уведомления.Но я не могу этого сделать.

Итак, вопрос в следующем: существует ли хитрый способ контролировать экземпляр объекта и определять, когда он уничтожается?

Ответы [ 4 ]

11 голосов
/ 16 июля 2010

Поскольку вы создаете объекты, кажется, что вы могли бы вернуть Decorator вместо фактического экземпляра.

Используя Pattern Decorator , вы можете "обернуть" возвращаемый объект в свой собственный, оформленный API. Украшение может предоставить IDisposable реализацию, которая предоставила ваше уведомление об уничтожении.

5 голосов
/ 16 июля 2010

Нет способа получить активное уведомление, но вы можете оставить WeakReference для объектов и периодически проверять, не умерли ли они.

Редактировать: Мне нравятся Ридответь лучше моего!

2 голосов
/ 16 июля 2010

Если вы удерживаете список ссылок на созданные вами экземпляры, они не будут собирать мусор и никогда не будут уничтожены ...

Вместо этого вы можете создать репозиторий, содержащий список направляющих исоздайте новый Guid для каждого экземпляра, а затем добавьте его в список - что-то вроде FactoryRepository.Таким образом, у вас нет проблем с ссылками для сборки мусора, так как Guids - это структуры, а не ссылочные типы.Затем вы можете наследовать от каждого класса, чтобы создать тип, который может уведомлять об уничтожении.Я предполагаю, что, поскольку вы не можете изменить код исходных классов, вы также не можете изменить потребителей этих классов, поэтому что-то вроде шаблона декоратора (через интерфейс) отсутствует, потому что типы не будут совместимы.

Очень упрощенный пример:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

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

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}
1 голос
/ 16 июля 2010

Как насчет контроля уничтожения объекта:

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?
}
...