Получить уведомление об удалении/уничтожении объекта
Мне нужен способ отслеживать экземпляры различных классов, без тех классов, которые знают, что они отслеживаются. По сути, у меня есть фабрика классов, которая создает экземпляры и передает их другому потоку. Как только этот поток завершает и выгружает экземпляр, мне нужно получить уведомление об этом, чтобы я мог сделать подсчет ссылок и выйти из моей фабрики классов, когда все экземпляры ушли.
проблема в том, что я не могу изменить ни один из классов, которые я буду bve нагрузки, потому что я не контролирую их исходный код.
отслеживание экземпляров, которые я создаю, просто, я могу просто поместить их в какую-то коллекцию, когда я их создаю. Отслеживание их уничтожения вызывает у меня проблемы. Если бы я мог изменить исходный код, я бы добавил событие к каждому классу, и когда я создаю экземпляр, я бы подключился к событию и использовал его в качестве уведомления. Но я не могу этого сделать.
Итак, вопрос в следующем: есть ли подлый способ контролировать экземпляр объекта и обнаружить, когда он разрушается?
4 ответов
нет способа получить активное уведомление, но вы можете сохранить WeakReference
к объектам и периодически проверяйте, не умерли ли они.
Edit: мне больше нравится ответ Рида, чем мой!
поскольку вы создаете объекты, кажется, что вы можете вернуть оформителя вместо фактического экземпляра.
с помощью Шаблон "Декоратор", вы можете "обернуть" возвращаемый объект в свой собственный, украшенный API. Украшение может обеспечить IDisposable реализацию, которая предоставила ваше уведомление об уничтожении.
Если вы держите список ссылок на созданные вами экземпляры, они не будут собирать мусор и поэтому никогда не будут уничтожены...
вместо этого вы можете создать репозиторий, содержащий список GUID, и создать новый Guid для каждого экземпляра, а затем добавить его в список - что-то вроде FactoryRepository. Таким образом, у вас нет ссылочной проблемы для сборки мусора, поскольку GUID-это структуры, а не ссылочные типы. Затем вы можете наследовать от каждого класса чтобы создать тип, который может уведомлять об уничтожении. Я предполагаю, что, поскольку вы не можете изменить код исходных классов, вы также не можете изменить потребителей этих классов, поэтому что-то вроде шаблона декоратора (через интерфейс) отсутствует, потому что типы не будут совместимы.
очень упрощенный пример:
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?
}