c#.NET中的事件驱动方法和执行顺序

时间:2011-10-26 08:40:00

标签: c# .net events methods

假设,如果我有两个由同一事件驱动的方法(事件处理程序),首先执行哪个方法?

示例:

obj.SomeEvent += new SomeEventHandler(method1);
obj.SomeEvent += new SomeEventHandler(method2);

首先叫哪个?

谢谢!

4 个答案:

答案 0 :(得分:4)

由事件发布者决定,但通常它将是首先添加到事件中的处理程序。这是基本上使用委托实现的事件的默认实现。例如:

SomeDelegate eventHandlers = null;
eventHandlers += FirstHandler;
eventHandlers += SecondHandler;
eventHandlers(...);

肯定FirstHandler之前调用SecondHandler。但是,无法保证只使用这样的代表才能实现 事件。

编辑:虽然事件处理行为取决于事件发布者,但是委托组合部分在C#语言规范第7.8.4节中明确指定:

  

[...]否则,操作的结果是一个新的委托实例,在调用时,调用第一个操作数,然后调用第二个操作数。

BCL Delegate.Combine方法提供了类似的保证(强调我的):

  

(返回值)一个新的委托,它有一个调用列表,用于按顺序连接a和b 的调用列表。返回如果b为null,则返回b,如果a为空引用,则返回b;如果a和b都为空引用,则返回空引用。

答案 1 :(得分:1)

第一个订阅的。 “先进先出”。

答案 2 :(得分:1)

默认实现将导致事件处理程序按添加顺序调用,但是,可以自定义此行为。如果行为是自定义的,则客户端无法告知此情况。因此,您的问题的真正答案是事件处理程序的提升顺序“取决于”,甚至可能在运行时更改,但是,绝大多数事件都具有默认实现。

例如:

public class ReverseBling
{
    private readonly List<EventHandler> _blings = new List<EventHandler>();

    public event EventHandler Bling
    {
        add
        {
            _blings.Add(value);
        }
        remove
        {
            _blings.Remove(value);
        }
    }

    public void RaiseBling()
    {
        for (int i = _blings.Count - 1; i >= 0; i--)
        {
            _blings[i](this, EventArgs.Empty);
        }
    }
}

private static void Main()
{
    ReverseBling bling = new ReverseBling();
    bling.Bling += delegate { Console.WriteLine(0);};
    bling.Bling += delegate { Console.WriteLine(1); };
    bling.Bling += delegate { Console.WriteLine(2); };
    bling.RaiseBling();
}

输出:

  

2
   1
   0

答案 3 :(得分:-1)

无法确定将首先调用哪个事件处理程序。许多人认为第一个订阅将首先被调用(通常是这种情况)但不是由CLI指定的。