【问题标题】:Store a list of EventHandlers to unsubscribe from存储要取消订阅的 EventHandler 列表
【发布时间】:2011-05-13 09:28:46
【问题描述】:

我有一个类,它有一个方法Register,它使用标准aClass.SomeEvent += the_handler 订阅它包含的类上的许多事件。此类还有一个Unregister 方法,该方法使用-= 取消订阅这些事件。这工作得很好,但我们发现如果我们添加一个新事件来订阅它很容易忘记在Unregister 中包含取消订阅。这种维护事件订阅的手动方法被证明是脆弱的。

有没有办法维护一个可以动态迭代和取消订阅的订阅列表? (并且在Unregister 之后调用Register 时可能会迭代并重新订阅)。

一些细节:该类引用了其他 3 个类(目前,但不限于 3 个),这些类上的各种事件都是 EventHandlerEventHandler<T> 类型。

【问题讨论】:

  • 好问题。我也在使用手动分离
  • @Heandel 始终注册和注销所有事件。规则没有例外。

标签: c# events reflection


【解决方案1】:

如何从EventHandler.GetInvocationList() 获取调用列表,然后遍历并手动删除/注销它们?请注意,您只能从具有该 EventHandler 的类中访问 GetInvationList() 方法,因此您可能需要公开一个方法 UnregisterAll() 以确保它删除事件调用列表中的所有委托

您还可以确保您的类继承 IDisposable 并使用 using(){ } 它会调用 Dispose 来清理所有订阅者

【讨论】:

  • 感谢您的回答,我也在考虑在每个类中迭代调用列表,但我看不出这是如何工作的。事件是/也可以被其他类订阅。如何遍历列表并仅从我的 Register 类中删除调用?
  • 这些类似乎也没有责任解开事件。也许如果我可以公开调用列表以便 Register 类可以看到它,但即便如此我也不知道如何通过迭代委托列表以编程方式取消订阅事件。 -= 不起作用,因为我无法告诉它要取消挂钩的方法。噩梦。
  • 是的,如果您只想为您的班级而不是其他班级删除/取消订阅,这很棘手。想不出比使用反射更好的方法,或者可能重新设计整个订阅过程(即不使用 EventHandler 但有自己的事件处理程序,它跟踪特定的类和订阅)。 EventHandler 包装事件,以便您可以轻松使用 -= 和 +=。也许你需要覆盖它
【解决方案2】:

经过彻底查看后,我找到了这个答案:

C# Dynamic Event Subscription

这就是我想要的(几乎)。我不喜欢使用字符串来命名事件,因此我不会进一步追求这种设计。尽管这不是我想要的设计,但答案显示了一种非常有用的方法来实现所需的行为,因此我将其标记为已接受。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 2020-11-11
    • 2019-01-31
    • 2017-05-12
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    相关资源
    最近更新 更多