事件驱动方法和执行顺序

本文关键字:顺序 执行 方法 事件驱动 | 更新日期: 2023-09-27 18:12:30

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

的例子:

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

先调用哪个?

谢谢!

事件驱动方法和执行顺序

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

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

肯定会SecondHandler之前调用FirstHandler。然而,不能保证事件将会仅仅使用这样的委托来实现。

编辑:虽然事件处理行为取决于事件发布者,委托组合部分在c#语言规范中有很好的规定,第7.8.4节:

[…否则,该操作的结果是一个新的委托实例,该实例在被调用时先调用第一个操作数,然后再调用第二个操作数。

BCL Delegate.Combine方法也做了类似的保证(重点是我的):

(返回值)一个带有调用列表的新委托,该列表将A和b 的调用列表按顺序连接在一起。如果b为空则返回a,如果a为空引用则返回b,如果a和b都为空引用则返回空引用。

第一个订阅的。"先到先得"

默认实现将导致事件处理程序按照它们被添加的顺序被调用,但是,可以自定义此行为。如果行为是自定义的,则客户端无法知道这一点。因此,您的问题的真正答案是,事件处理程序引发的顺序"取决于",甚至可能在运行时更改,然而,绝大多数事件都具有默认实现。

例如:

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

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