2013-08-21 2 views
2

Допустим, мы имеем следующую модель:Удаление обработки событий в деструкторов в случае как издатель и подписчик держать ссылки на друг друга

public class Bar<T>:List<T> 
    { 
     public delegate void CollectionChangedDelegate(); 
     public event CollectionChangedDelegate CollectionChanged; 
    } 

    public class Foo 
    { 
     Bar<object> MyCollection = new Bar<object>(); 

     public Foo() 
     { 
      MyCollection.CollectionChanged += new Bar<object>.CollectionChangedDelegate(MyCollection_CollectionChanged); 
     } 

     public void MyCollection_CollectionChanged() 
     { 
      //Do Something 
     } 

     ~Foo() //Would this work ? 
     { 
      MyCollection.CollectionChanged -= MyCollection_CollectionChanged; 
     } 
    } 

Может деструктор класса Foo называться в этом случае?

+0

Вы не должны использовать деструкторов, используйте IDisposable интерфейс вместо. Ответьте на свой вопрос: если ни один другой живой объект не имеет ссылки на класс Foo, они будут собраны, см. Http://stackoverflow.com/questions/2775520/c-sharp-garbage-collector-cross-reference –

ответ

3

Это бессмысленно. Предположим, что есть такая подписка. Теперь, чтобы перейти к методу ~Foo, мы должны быть собраны, поэтому мы должны быть недоступны. Из-за того, как работают события, подписки делают нас доступными (у издателя есть ссылка на подписчика) - поэтому мы можем сделать вывод, что MyCollection is также недоступен. Если бы это было не так, нас не собирали.

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

Удалить ~Foo: здесь бессмысленно; на самом деле, это хуже, чем бессмысленный - в дополнение к сервису нецелесообразной цели он заставляет сборщик мусора продвигать этот объект через дополнительный шаг (очередь финализатора).

Вы можете, однако, добавить какой-то детерминированный очистка, которая делает это; как отмечает Йорен, IDisposable может быть полезным - однако трудно сказать, подходит ли это в случае, не зная большего контекста.

+0

Хорошо, чтобы сделать его простым. Foo будет собран независимо от того, что правильно? И нет необходимости в деструкторе? И вы сказали, что MyCollection должен быть недоступен, как я могу это гарантировать? Допустим, что я сделал и экземпляр Foo, таким образом, и экземпляр Bar (MyCollection) тоже будет сделан, как я могу гарантировать, что MyCollection будет собрано и недостижимо к концу области? –

+0

Также только для класса Note Foo представляет собой бизнес-объект в системе, над которой я работаю, и тщательно используется везде (Thats, почему IDisposable не является вариантом). Я пытаюсь выяснить, может ли это быть причиной утечки памяти? Один из разработчиков в нашей команде, утверждает, что это так, и что он добавил деструктора и протестировал его эффект на очистку памяти. Я хотел бы убедиться в этом –

+0

@SirajMansour Я говорил о сценарии, в котором вызывается '~ Foo': для этого мы можем * вывести *, что сборник был недоступен (иначе мы бы не попали туда). Что касается его недостижимости - ну, на данный момент это личное поле - единственное, что может знать об этом, - это экземпляр «Foo». Основываясь на * показанном коде * (и *** только *** показанном коде), я снова говорю: '' Foo' * хуже *, чем бесполезно. Он не имеет хороших эффектов и определенного отрицательного эффекта. –

2

Прежде всего, я считаю, что вы пытаетесь написать ObservableCollection
Здесь вы можете найти информацию: http://msdn.microsoft.com/en-us/library/ms668604.aspx.

Теперь, если в моем объекте содержатся члены данных, которым необходимо распоряжаться, я бы выполнил IDisposable и там я их удалю или, по крайней мере, удалю подписку на события.
implment это так:

class Foo:Idisposable 
{ 
    public void Dispose(bool b) 
    { 
     MyCollection.CollectionChanged -= MyCollection_CollectionChanged; 
    } 
} 
+0

Я не пытаюсь написать это, на самом деле уже написано, и я работаю над утечкой памяти. Я задаюсь вопросом, будет ли это причиной утечки памяти, потому что класс Foo представляет собой бизнес-объект в системе, над которой я работаю, и тщательно используется везде. –

Смежные вопросы