2

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

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

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

然而。如果对象还没有被垃圾回收(但是没有更多的强引用),那么事件处理程序仍然会被调用。

我的问题比较笼统:使用弱事件时应该怎么做?使用弱事件时,我应该期待事件处理程序中的无效调用吗?还是我应该强制 GC避免这种情况(某种确定性的“清理”)?还有什么?

4

1 回答 1

3

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

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

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

如果委托人在ev = MyEvent和之间未注册ev.Invoke,它仍会尽早收到通知。我有没有提到并发编程很困难?

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

于 2016-04-21T10:37:11.157 回答