2013-07-15 84 views
2

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

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

+1

你*不应该*编写依赖这种行为的程序。你需要*关心*是一个*大*红旗。 – Servy

+0

如果您认为Microsoft无法彻底改变,您一定没有听说过Xbox One(Eighty) – Sayse

+0

@HappyNomad - 我为游戏做了一些编程,所以我一直关注它们,简单地说,微软起初基本上说过只能在一个控制台上玩一个你买过的游戏,然后完全改变主意。 – Sayse

回答

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; 
} 
+0

好点!我没有考虑过“add”和“remove”关键字。 – HappyNomad

0

这取决于事件如何实施。

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

其他事件可以按照其他顺序自由存储其处理程序。然而,最不规范的实现仍然使用被窝里多路广播委托,存储在不同的方式(例如,EventHandlerList

+0

当前.NET框架版本的数量不是开放式的,所以我想要一个更具体的答案。 – HappyNomad

+2

@HappyNomad您需要在特定类中定义特定事件才能获得定义的答案。 – Servy

+0

你是什么意思?事件是使用C#中的'event'关键字定义的。不要处理所有这些事件的注册工作是一样的吗? – HappyNomad

相关问题