我可以依赖于按注册顺序调用的事件处理程序吗?

时间:2013-07-15 15:05:42

标签: c# event-handling .net-4.5 implementation

在.NET框架的当前版本中,并且在正常情况下(即,无需故意修改调用列表),事件总是的处理程序是按照它们的注册顺序调用的吗?这与多播委托的记录行为一致,实现了哪些事件。

this question接受的答案表示按照注册顺序调用处理程序是一个实现细节,可能会在框架的某个未来版本中发生变化。我相信微软不太可能做出这样的改变,因此我将我的问题局限于当前版本的.NET框架。对同一个答案的评论说,可以注册处理程序,使其在注册顺序中。如果这是真的,请演示导致此无序执行的代码。请不要包含故意修改调用列表的代码。我在这里说的是,我是否可以依赖于事件处理程序调用与.NET框架的所有当前版本中的注册顺序相同。

2 个答案:

答案 0 :(得分:2)

您无法确定事件将始终按特定顺序执行。事件的定义总是可以做任何事情,并且该事件的实现不是公共API的一部分。

默认情况下,事件将使用单个多播委托作为事件的后备存储,但它足以直接使用您自己的实现。除了查看源代码之外,没有办法告诉事件是否有自定义实现。

实现事件以使其没有描述顺序的一种方法是:

public class Foo
{
    private Stack<Action> stack = new Stack<Action>();

    public event Action MyEvent
    {
        add
        {
            stack.Push(value);
        }
        remove { throw new NotImplementedException(); }
    }

    internal void OnMyEvent()
    {
        foreach (var action in stack)
            action();
    }
}

虽然框架类中的大多数事件都不会使用这样的定义;大多数人都会使用多播委托,知道的唯一方法就是查看源代码;你无法分辨,例如,查看文档,事件是否像这样实现或类似:

public class Foo2
{
    public event Action MyEvent;
}

答案 1 :(得分:0)

这取决于事件的实施方式。

普通(类似字段的)事件将所有处理程序存储在单个多播委托中。
多播委托以插入顺序调用其处理程序。

其他事件可以自由地以其他顺序存储其处理程序。但是,大多数非标准实现仍然使用多种代理,以各种方式存储(例如,EventHandlerList