我需要从对象中删除事件订阅他们被孤立过吗? [英] Do I need to remove event subscriptions from objects before they are orphaned?

查看:78
本文介绍了我需要从对象中删除事件订阅他们被孤立过吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我的软件有两个对象实例,其中一个被订阅的其他的事件。我需要从一个退订他们,他们是孤立另一个之前,对它们进行清理被垃圾收集器?或者有没有其他的原因,我应该清除事件的关系?如果什么认购对象是孤立的,但用户是不是,反之亦然?

If my software has two object instances, one of which is subscribed to the events of the other. Do I need to unsubscribe them from one another before they are orphaned for them to be cleaned up by the garbage collector? Or is there any other reason why I should clear the event relationships? What if the subscribed to object is orphaned but the subscriber is not, or vise versa?

推荐答案

是的,你做的。事件出版商抱着引用的对象,将$ P $被垃圾收集pvent他们。

Yes you do. The event publishers are holding references to the objects, and would prevent them from being garbage collected.

让我们来看一个例子,看看会发生什么。我们必须班; 1暴露了一个事件,其他消耗它

Let's look at an example to see what happens. We have to classes; one exposes an event, the other consumes it:

class ClassA
{
    public event EventHandler Test;
    ~ClassA()
    {
        Console.WriteLine("A being collected");
    }
}
class ClassB
{
    public ClassB(ClassA instance)
    {
        instance.Test += new EventHandler(instance_Test);
    }

    ~ClassB()
    {
        Console.WriteLine("B being collected");
    }

    void instance_Test(object sender, EventArgs e)
    {
        // this space is intentionally left blank
    }
}

请注意如何ClassB的不存储引用ClassA的实例;它只是挂接事件处理程序。

Note how ClassB does not store a reference to the ClassA instance; it merely hooks up an event handler.

现在,让我们看看如何对象的收集。方案1:

Now, let's see how the objects are collected. Scenario 1:

ClassB temp = new ClassB(new ClassA());
Console.WriteLine("Collect 1");
GC.Collect();
Console.ReadKey();
temp = null;
Console.WriteLine("Collect 2");
GC.Collect();
Console.ReadKey();

我们创建ClassB的实例,并通过召开临时变量对它的引用。它传递了ClassA的,在这里我们引用不存储任何地方的一个新实例,如此这般的ClassB的构造是做超出范围后,立即。我们有垃圾收集器运行一次的ClassA的时候已经超出了范围,而一旦当ClassB的是超出范围。输出:

We create a ClassB instance and hold a reference to it through the temp variable. It gets passed a new instance of ClassA, where we do not store a reference to it anywhere, so it goes out of scope immediately after the ClassB constructor is done. We have the garbage collector run once when ClassA has gone out of scope, and once when ClassB as gone out of scope. The output:

Collect 1
A being collected
Collect 2
B being collected

情景2:

ClassA temp = new ClassA();
ClassB temp2 = new ClassB(temp);
temp2 = null;
Console.WriteLine("Collect 1");
GC.Collect();
Console.ReadKey();
temp = null;
Console.WriteLine("Collect 2");
GC.Collect();
Console.ReadKey();

ClassA的的一个新实例被创建,对它的引用存储在临时变量。然后ClassB的新实例被创建,获得在温度传递给它的ClassA的实例,我们存储对它的引用在TEMP2。然后,我们设置TEMP2为null,使ClassB的实例走出去的范围。和以前一样,我们有垃圾收集器运行后,每个实例都已经超出了范围。输出:

A new instance of ClassA is created and a reference to it is stored in the temp variable. Then a new instance of ClassB is created, getting the ClassA instance in temp passed to it, and we store a reference to it in temp2. Then we set temp2 to null, making the ClassB instance going out of scope. As before, we have the garbage collector run after each instance has gone out of scope. The output:

Collect 1
Collect 2
B being collected
A being collected

因此​​,得出结论;如果暴露事件实例超出范围,就成了可进行垃圾回收,而不管是否有事件处理程序挂钩与否。如果具有挂接到在另一个实例的事件的事件处理程序的一个实例,它不会是可用于垃圾收集,直到该事件处理程序被分离,或实例,以该事件处理程序被安装用于垃圾收集变得可用。

So, to conclude; if the instance that exposes an event goes out of scope, it becomes available for garbage collection, regardless of whether there are event handlers hooked up or not. If an instance that has an event handler hooked up to an event in another instance, it will not be available for garbage collection until either the event handler is detached, or the instance to which the event handler is attached becomes available for garbage collection.

这篇关于我需要从对象中删除事件订阅他们被孤立过吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆