注册委托和注册事件的命名方法之间的区别

时间:2012-08-25 23:06:26

标签: c# events delegates

我想确认一些事情 - 当我将方法注册为事件的订阅者时,很长一段路,就像这样:

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

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

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

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

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

        };
}

无法从该方法的订户列表中取消注册该委托。所以我假设这个注册的范围仅限于它注册的方法 - 即如果在ThisMethod调用的方法中触发了_serviceContext.ReadingEntity事件,那么这个注册已经过期并且里面的代码代表不会运行。它是否正确?

谢谢!

P.S。我意识到第一个&#34;长&#34;注册事件处理程序的方式也有范围限制,但我对此有点朦胧。然而,我的主要问题是,代表注册是否将在上述方法之外生效。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

如果你保留对它的引用,你可以取消订阅。

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

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

如果你不这样做,就无法取消订阅。范围不限于其注册的方法。它将在活动的整个生命周期内注册。