弱事件和GC

Weak events and GC

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

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 来避免这种情况(某种确定性 "clean up")?还有别的吗?

即使有 "strong" 个事件,您也应该始终期望在您注销后可能会调用事件处理程序。这样的调用没有什么无效的。

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

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

如果代表在ev = MyEventev.Invoke之间取消注册,它仍然会第一时间收到通知。我有没有提到并发编程很难?

但在您的情况下,问题确实是 "why doesn't the object know when to unregister?" 回答这个问题,您就会找到解决方案。为什么调用针对不再在任何地方被强引用的对象的事件处理程序是非法操作?这不像对象已部分收集或其他任何东西 - 它只是尚未收集。