2

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

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

4

2 回答 2

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;
}
于 2013-07-15T15:14:15.123 回答
0

这取决于事件是如何实现的。

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

其他事件可以自由地以其他顺序存储它们的处理程序。然而,大多数非标准实现仍然在幕后使用多播委托,以各种方式存储(例如,EventHandlerList

于 2013-07-15T15:07:55.043 回答