Возможно, этот подход имеет смысл, если вы не можете избавиться от потокобезопасности (например, при разговоре с объектами COM, которые ДОЛЖНЫ быть выпущены в том же потоке). Однако на практике вы обнаружите, что этот подход приводит к тому, что объекты живут дольше, чем нужно.
Я бы стремился сделать поток отходов безопасным, таким образом вы можете позвонить Dispose
из финализатора и добиться поистине автоматического управления жизненным циклом. Вы должны быть осторожны, поскольку это не подходит для некоторых типов ресурсов - например, файлов или сетевых ручек, для которых может потребоваться более жесткий контроль. В противном случае это наилучшим образом решение этой проблемы.
Если распоряжение должно быть на одной и той же резьбе, то вы находитесь в немного рассола. Если объект, нуждающийся в утилизации, находится на уровне модели (как и в объекте бизнес-правил) - вполне вероятно, что на нем есть слои пользовательского интерфейса, требующие сложной логики для его удаления (например, события после закрытия окна).Это потерянная/потерянная ситуация и выбор между объектами, живущими вечно (например, ваше оригинальное решение) и сложной логикой утилизации (которая становится довольно уродливой довольно быстро).
Возможно, что-то экспериментировать с. Вы можете отделить одноразовый ресурс в своем собственном классе, и на его фабрике будет содержаться ссылка на него. Объект ресурса сохраняет слабую ссылку на бизнес-объект. Когда бизнес-объект будет завершен, WeakReference
вернет null
, что позволит вам пройти через одноразовые предметы и сбросить те, которые больше не нужны.
public class Global {
private static readonly List<Resource> Disposables = new List<Resource>();
public HeavyLifter GetHeavyLifter()
{
var resource = new HeavyLifterResource();
var heavyLifter = new HeavyLifter(resource);
resource.BusinessObject = heavyLifter;
Disposables.Add(resource);
}
public void DisposeAll()
{
Disposables.ForEach(d => d.CleanUp());
}
}
public abstract class Resource : IDisposable {
WeakReference<object> m_BusinessObject;
public WeakReference<object> BusinessObject {get;set;}
public CleanUp() {
if (!m_BusinessObject.IsAlive)
Dispose();
}
}
public HeavyLifter {
public HeavyLifter (Disposable d) {
m_resourceObj = d;
}
HeavyLifterResource m_resourceObj;
}
public class HeavyLifterResource :Resource {
public void Dispose() {
//disposal
}
}
Позвольте мне еще раз повторить, что приведенный выше подход подходит только для определенного класса объектов. Вы не хотите обрабатывать сетевые подключения таким нечетким образом, но вы можете, например, сделать это для бизнес-объектов, которым требуется сетевое подключение, чтобы распоряжаться собой. Даже тогда это подходит только тогда, когда такое соединение является постоянным в течение всего срока службы приложения.
Что вы пытаетесь сделать с этим? – dtb
Я хочу зарегистрироваться для удаления на создание ресурса и не забудьте сделать это в другом месте на расстоянии 100 строк. Я думаю, что больше не подходит для рефакторинга, чтобы не разбрызгивать фрагменты кода во всех классах. Моя неопределенность заключается в том, что возможны проблемы, которые могут привести к утечкам памяти, проблемам потокобезопасности и т. Д. – Jan
IDisposable должен помочь вам решить эти проблемы, а не создавать новые. Если вы сделаете свои методы удаления потоком безопасными и очистите все неуправляемые ресурсы, которые хранятся в каждом отдельном объекте, реализующем dispose, я думаю, что у вас будет идеальная ситуация. –