如何控制触发事件处理程序的顺序?

时间:2008-11-05 02:28:08

标签: .net events

事件处理程序是否按照它们附加到事件的顺序触发?如果没有,我可以在事件处理程序上强制执行某种顺序,以便按特定顺序调用它们吗?

5 个答案:

答案 0 :(得分:18)

假设事件的简单实现(在委托字段上使用+ =和 - =,然后使用Delegate.Combine/Remove)然后是,则将按照它们的顺序调用事件处理程序认购。保证在Delegate.Combine文档中有效地给出:

  

返回值

     

新的多播(可组合)委托   有一个调用列表   连接 a 的调用列表   和 b 按此顺序。

请参阅我的article about events,了解Delegate.Combine/Remove做的一些示例(以及幕后的事件)。

答案 1 :(得分:4)

NOT 依赖于事件排序。所有事件调度都应该在逻辑上独立,就好像它们是并行发生的一样。

在其他类和线程中添加事件处理程序可能会干扰您的假设排序,这不是一个安全的假设,它违背了事件的概念作为独立的解耦操作。

我会更进一步,断言如果你必须承担一个事件发生的命令,你就会有严重的设计缺陷和/或滥用事件。

答案 2 :(得分:2)

您可能有一个事件处理程序以指定的顺序调用其他函数或委托。

答案 3 :(得分:2)

我建议“包装它。”

做这样的事......

MyObject.MyEvent += new MyEventHandler(Wrapper);

public void Wrapper()
{
    Method1();
    Method3();
    Method2();
}

通过这种方式,你仍然可以挂钩事件,但可以完全控制所谓的事件。

答案 4 :(得分:0)

很抱歉迟到的回复。


我遇到过一种情况,我必须处理事件处理程序的顺序。

我有一个表单,当我单击表单上的一个按钮时,会在我的代码中的某个位置添加一个对象。

该集合有一个“已添加”事件,并且两个代表已被挂钩。其中一个方法删除刚刚添加到集合中的任何项目,而另一个方法则向用户显示消息。


如果我在这里显示了一些代码,则在触发事件时会抛出“IndexOutOfRange”异常:

// this methods hooks two delegates to MyCollection.Added event, but the order results in a "IndexOutOfRange" exception after the event is triggered
HookEvents()
{
   MyCollection.Added += new CollectionItemAddedHandler(DeleteItem_After_CollectionItemAdded);

   MyCollection.Added += new CollectionItemAddedHandler(ShowMessage_After_CollectionItemAdded);
}


// when user click a button on form, add a object to MyCollection
Button_Clicked()
{
   MyCollection.Add(new object());     
}

// at the moment a object is added into the collection, this method remove it
DeleteItem_After_CollectionItemAdded(NewIndexArgs e)
{
    MyCollection.Remove(e.NewIndex); // e.NewIndex represents the newly added item index in current collection  
}

// at the moment a object is added into the collection, this method show its information (hey, but remember, I just remove it in the previous method)
ShowMessage_After_CollectionItemAdded(NewIndexArgs e)
{
    MessageBox.Show(MyCollection[e.NewIndex]); // tell user what is just added into the current collection
    // a "IndexOutOfRange" exception is thrown here....
}

使此方案正常工作正确的原因是“ShowMessage_After_CollectionItemAdded”方法应该先触发 ,然后才能成为“DeleteItem_After_CollectionAdded”方法。

虽然我们首先可以+ =“ShowMessage ...”方法,但有时我们无法在运行时之前预定义此序列。