弱事件和GC

时间:2016-04-21 10:26:24

标签: c# garbage-collection weak-events

当我无法确定取消订阅时,我会使用弱事件(否则我会更喜欢+=-=而不是弱事件):

class SomeType
{
    public SomeType(...)
    {
        // object doesn't know when it will be removed
        WeakEventManager(SomeSource, EventArgs).AddHandler(someSourceInstance,
            nameof(SomeSource.SomeEvent), (s, e) => { ... });
    }
 }

这样,如果对象被垃圾收集,则不会调用事件处理程序。完美。

然而。如果对象尚未垃圾收集(但没有更强的引用),则仍将调用事件处理程序。

我的问题相当笼统:在使用弱事件时我该怎么办?在使用弱事件时,我是否期望在事件处理程序中无效调用?或者我应该force GC来避免这种情况(某种确定性的"清理")?还有别的吗?

1 个答案:

答案 0 :(得分:3)

您应该始终期望在您取消注册后可以调用事件处理程序,即使是“强”事件也是如此。这样的电话没有任何效果。

当您查看事件处理程序的执行方式时,最简单的场景是显而易见的:

protected void OnMyEvent(object sender, EventArgs e)
{
  var ev = MyEvent;
  if (ev != null) ev(this, EventArgs.Empty);
}

如果代理人在ev = MyEventev.Invoke之间取消注册,它仍会尽早收到通知。我是否提到并发编程很难?

但在您的情况下,问题实际上是“为什么对象不知道何时取消注册?”回答这个问题,你会得到解决方案。为什么调用一个以不再强引用的对象为目标的事件处理程序是非法操作?这不是对象被部分收集或任何东西 - 它只是尚未收集。