【发布时间】:2011-01-02 13:53:03
【问题描述】:
注意:我编辑了这个问题是为了让其他有同样问题的人更容易在这里获得帮助。要查看更适合某些答案的原始问题,请查看编辑历史记录。
在一个项目中,我有一个 ExecutionManager 类,它可以包含多个 ExecutionSlot 的实例。 ExecutionSlot 类有几个公共事件字段,如下所示:
public event EventHandlers.ObjectEventHandler<IPlugin> ExecuteCompleted;
对于这些事件中的每一个,在 ExecutionManager 上都有一个匹配的事件。期望的行为是每次 ExecutionSlot 引发一个事件时,匹配的事件也会在包含的 ExecutionManager 上引发。
实现的解决方案是,每当将 ExecutionSlot 添加到 ExecutionManager 时,ExectionManager 都会将自己的事件添加到 ExecutionSlot,如下所示:
executionSlot.ExecuteCompleted += ExecuteCompleted;
目前还不需要移除 ExecutionSlot,因此事件也永远不会被移除。
问题是没有引发 ExecutionManager 上的事件。在确认 ExecutionSlot 正在触发事件后,我发现将上面的行更改为以下内容可以解决问题:
executionSlot.ExecuteCompleted += (sender, eventArgs) => ExecuteCompleted(sender, eventArgs);
我不知道为什么,所以我的问题是,有什么区别。
造成这种差异的原因是第一个将 ExecutionManager 事件的当前侦听器添加到 ExecutionSlot 事件中。因此,在引发事件时,不会调用以后添加的任何侦听器。 相比之下,后一种解决方案使用 lambda 来引发 ExecutionManager 的事件,这意味着将调用事件发生时的侦听器。
第一个解决方案失败的根本原因是委托是不可变的。因此,当您向事件添加新委托时,您实际上是在创建一个新委托,其中包含现有委托和添加的委托。所以之前对委托的任何引用都不会包含新添加的委托。
【问题讨论】:
-
也许可以将您的编辑恢复为原来的问题,然后提出另一个问题并回答它,来回引用?
-
我明白保留原文的意义,因为这就是这里的答案。但由于原文不够清晰,我觉得比起几乎重复的问题,新的文本对其他人的帮助会更好。
标签: c# .net events .net-3.5 delegates