【问题标题】:Checking if an event handler exists检查是否存在事件处理程序
【发布时间】:2010-12-19 13:36:42
【问题描述】:

this post 开始 - 当我只希望触发一个处理程序事件时,使用-= 然后建议使用+= 方法有什么缺点?

_value.PropertyChanged -= _handlerMethod;
_value.PropertyChanged += _handlerMethod;

【问题讨论】:

    标签: c# event-handling


    【解决方案1】:

    这并不能保证只触发一个处理程序。

    另一个位置可能会多次为您的处理程序订阅您的事件。在这种情况下,您只会删除第一个处理程序调用。

    如果您确实希望一次只订阅一个处理程序,则通过检查事件的调用列表,您可以保证这种行为。

    【讨论】:

    • 附带说明,这两行也不会影响已添加的任何其他处理程序。我相信这两个语句的唯一影响是附加处理程序的可能重新排序。
    • 没错。您只需保证在调用列表的末尾有一个 _handlerMethod(尽管规范不保证排序),而不是那里没有其他实例。
    • 如何在运行时检查调用列表(c#)?
    • 查看您引用的帖子中的第一个答案。基本上,您使用 Delegate.GetInvocationList() 来获取委托数组(它们是被调用的方法)。然后,您可以直接检查它们。您还可以覆盖事件的添加/删除处理程序以保证单个方法实例(总数不超过一个,或每个委托一个等)。见:msdn.microsoft.com/en-us/library/…
    【解决方案2】:

    如果您真的只希望执行一个处理程序,那么您可能希望使用适当委托类型的可设置属性而不是事件。仅存储一名代表;您可以像执行事件处理程序一样执行委托。

    【讨论】:

      【解决方案3】:

      这里的想法是,如果您的事件处理程序未分配,-= 运算符将不会做任何事情。

      我个人不喜欢这种方法,我认为您应该真正致力于重构您的代码,以便您知道事件处理程序只分配一次。

      缺点是: - 竞争条件的可能性,如果您的应用程序是多线程的并且在未分配处理程序时触发事件 - 我也不确定当你运行 _value.PropertyChanged -= _handlerMethod 当处理程序的两个副本已经分配时会发生什么。 - 乱七八糟的代码 - 显然从代码中不清楚哪个类以及何时监听事件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多