如何安全地摆脱事件处理程序?

pbe*_*ean 7 c# events

假设我有一个类A可以触发一个名为X的事件.现在我有一个B类,在一个方法中我得到一个实例到A并将事件绑定到B中的一个处理程序:

public void BindEvent(A a)
{
    a.X += AEventHandler;
}
Run Code Online (Sandbox Code Playgroud)

我有三个问题.

  • 当我现在将对B实例的引用设置为null时,它不会被垃圾收集,因为垃圾收集器认为它仍然在使用(因此在内存中保留了无用且可能干扰的B副本).

  • 当我有另一个对象c(C类)时,我有一个名为a的引用("this.a = new A()").然后我调用"b.BindEvent(this.a)",在c中我将a的引用设置为null("this.a = null").这会将A的副本保存在内存中,因为它是通过b中的事件引用的吗?

  • 如果其中任何一个或两个都是如此,我怎样才能最好地规避这些问题呢?如果我有一个事件处理程序的完整列表(比如"a.SomeEvent + = SomeMethod"这样的10行),我应该再次清理它们("a.SomeEvent - = SomeMethod").我应该在代码中的哪个时间或地点做这些事情?

嗯,它有点模糊,但我不知道如何以更好的方式解释.如果我需要解释更详细的内容,请发表评论.

Mar*_*ell 8

那么:A是出版商B还是订阅者?

第一弹:如果B是实例与AEventHandler-那么它仍然在使用,所以没有,也不会得到收集,除非a情况不可达.

第二个子弹:嗯?(将再次阅读...)如果AB实例都无法访问,它们将被垃圾收集; 事件没关系.如果A可以到达,那么B将保持活力.然而,事件订阅从未保持A活着; 这是一种方式...... A可以保持B活力,但B不能保持A活力.这涵盖了吗?

第三个问题:在大多数情况下,这两件事具有相似的生活费用,所以这不是问题.如果发布事件的事物比处理事件的事情长得多,那么它只会成为一个问题.在这种情况下,你只需要在自己之后进行宗教清理 - 例如:a.X -= AEventHandler.特别是,由于这个原因,static事件是邪恶的.