0

我想确认一些事情——当我将一个方法注册为一个事件的订阅者时,就像这样:

_serviceContext.ReadingEntity += new EventHandler<ReadingWritingEntityEventArgs>(_serviceContext_ReadingEntity);

如果我不希望在触发事件时继续调用该方法,我需要从事件的订阅中取消注册该方法,如下所示:

_serviceContext.ReadingEntity -= new EventHandler<ReadingWritingEntityEventArgs>(_serviceContext_ReadingEntity);

当我将委托注册为事件的订阅者时,如下所示:

public guy ThisMethod()
{
    _serviceContext.ReadingEntity += delegate(object sender, ReadingWritingEntityEventArgs e)
        {

        };
}

无法通过该方法从订阅者列表中取消注册该委托。因此,我假设此注册的范围仅限于其注册的方法 - 即,如果 _serviceContext.ReadingEntity 事件在 ThisMethod 调用的方法中被触发,则此注册已经过期,并且委托中的代码不会跑。它是否正确?

谢谢!

ps 我意识到注册事件处理程序的第一个“长”方式也有范围限制,但我对此有点模糊。然而,我的主要问题是委托注册是否会在上述方法之外继续存在。

4

2 回答 2

1

一旦您以这种方式订阅了委托(-=如果您在某处缓存委托变量,则可以使用运算符取消订阅),您无法将其从订阅者列表中删除,并且每次事件上升时都会调用它,直到发布者还活着。此外,此订阅阻止任何订阅者类(包含您订阅事件的方法的类)进行垃圾收集,直到发布者处于活动状态(除非您使用静态方法)。

为了清楚起见,IL 代码中没有“匿名”方法。您所有的委托和 lamdbas 都被转换为静态/实例方法和闭包类(取决于它们是否使用实例成员/函数参数)。

于 2012-08-25T23:10:59.207 回答
1

如果您保留对委托的引用,则可以取消订阅委托。

EventHandler<ReadingWritingEntityEventArgs> aDelegate = delegate(object sender, ReadingWritingEntityEventArgs e)
    {

    };
_serviceContext.ReadingEntity += aDelegate;
_serviceContext.ReadingEntity -= aDelegate;

如果您不这样做,则无法取消订阅。范围不限于注册方法。它将在事件的整个生命周期内注册。

于 2012-08-25T23:15:39.377 回答