控件已订阅其事件的垃圾收集和局部变量

时间:2011-02-24 10:57:42

标签: c# garbage-collection

如果c#类声明了一个变量,比如一个ObservableCollection,那么 订阅该变量上的事件,这是否会阻止控件被垃圾回收。换句话说,在以下情况下,SomeClass类可用于垃圾收集:

public class SomeClass
{
    private ObservableCollection<string> _someCollection = new ObservableCollection<string>();

    public SomeClass()
    {
        _someCollection.CollectionChanged += OnSomeCollectionCollectionChanged;
    }

    private void OnSomeCollectionCollectionChanged(object sender,NotifyCollectionChangedEventArgs e )
    {
    }
}

2 个答案:

答案 0 :(得分:4)

假设其他任何内容都没有引用ObservableCollection,则它们都有资格进行垃圾回收。

但是,如果其他内容使ObservableCollection保持活动状态,则从集合到SomeClass实例的引用(通过事件)也会使SomeClass对象保持活动状态。

编辑:澄清评论...... GC完全能够收集两个相互引用的对象,只要没有其他内容指的是它们。例如:

               /---->----\
  X ---->---- Y           Z
(root)         \----<----/

这里对象“X”充当根,即垃圾收集器知道应该保持活动的东西(例如,它是从线程中的堆栈中的局部变量引用的,或者它是通过静态变量引用。)

现在想象从X到Y的引用被切断了:

               /---->----\
  X           Y           Z
(root)         \----<----/

现在X仍然作为GC根保持活动,但是没有“实时”对象引用Y或Z,因此它们都可以被垃圾收集。他们互相提及的事实是无关紧要的。

答案 1 :(得分:1)

当您执行O.E += Y(其中E为事件)时,对象O将引用Y。这意味着在取消订阅或Y收集之前,无法收集O。没有什么可以阻止O被收集。