事件处理程序执行顺序

Phi*_*gan 86 c# asynchronous event-handling

如果我设置了多个事件处理程序,如下所示:

_webservice.RetrieveDataCompleted += ProcessData1;
_webservice.RetrieveDataCompleted += ProcessData2;
Run Code Online (Sandbox Code Playgroud)

事件RetrieveDataCompleted被触发时处理程序的运行顺序是什么?它们是否在同一个线程中运行并按顺序运行?

Ree*_*sey 122

目前,它们按照注册顺序执行.但是,这是一个实现细节,我不会依赖于此行为在未来版本中保持不变,因为规范不要求它.

  • 为了澄清,订单取决于特定事件的后备存储.事件的默认后备存储,多播委托,记录为按注册顺序执行.这在将来的框架版本中不会改变.可能会发生变化的是用于特定事件的后备存储. (14认同)
  • 因为它在2分上实际上是不正确的.1)目前它们按照*特定事件*的实现顺序执行 - 因为您可以为事件实现自己的添加/删除方法.2)当通过多播代理使用默认事件实现时,实际上规则要求订单. (5认同)
  • 我想知道,为什么倒下?这是完全正确的,直接回答问题...... (4认同)
  • @Rawling:这是二进制运算符重载决策 - 而不是事件处理.在这种情况下,这不是加法运算符. (2认同)
  • 啊,我看到我出错的地方:"事件处理程序是代表,对吧?".我现在知道他们不是.写了一个事件,以相反的顺序触发处理程序,只是为了向自己证明:) (2认同)

Phi*_*ace 52

委托的调用列表是一组有序的委托,其中列表的每个元素都只调用委托调用的方法之一.调用列表可以包含重复的方法.在调用期间,委托按照它们在调用列表中出现的顺序调用方法.

从这里: 代表班

  • 不错,但是使用 `add` 和 `remove` 关键字,事件可能不一定被实现为多播委托。 (2认同)

Nas*_*adi 11

您可以通过分离所有处理程序,然后按所需顺序重新附加来更改排序.

public event EventHandler event1;

public void ChangeHandlersOrdering()
{
    if (event1 != null)
    {
        List<EventHandler> invocationList = event1.GetInvocationList()
                                                  .OfType<EventHandler>()
                                                  .ToList();

        foreach (var handler in invocationList)
        {
            event1 -= handler;
        }

        //Change ordering now, for example in reverese order as follows
        for (int i = invocationList.Count - 1; i >= 0; i--)
        {
            event1 += invocationList[i];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Rex*_*x M 9

订单是任意的.您不能依赖从一次调用到下一次调用的任何特定顺序执行的处理程序.

编辑:而且 - 除非这只是出于好奇 - 你需要知道的事实表明一个严重的设计问题.

  • 要让一个需要由不同类以圆圈顺序处理的事件对我来说似乎不是一个严重的设计问题.如果事件注册以难以知道订单或事件的方式完成,则会发生问题,以便知道订单很重要. (9认同)
  • 顺序取决于特定事件的实现,但它不是**任意的.但是,除非事件的文档表明调用顺序,否则我同意依赖它是有风险的.在那种情况下,我发布了一个[后续问题](http://stackoverflow.com/questions/17659253/documenting-an-events-invocation-order). (3认同)

Bob*_*Bob 8

它们按照注册顺序运行.RetrieveDataCompleted多播代表.我正在通过反射器来尝试验证,看起来像是在幕后使用数组来跟踪所有内容.