Получить уведомление об удалении / уничтожении объекта

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

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

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

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

4 ответа

Решение

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

Изменить: мне нравится ответ Рид лучше, чем мой!

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

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

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

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

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

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

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

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}

Как насчет того, чтобы контролировать разрушение объекта:

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?
}
Другие вопросы по тегам