【问题标题】:Prioritising Event Handlers优先处理事件处理程序
【发布时间】:2011-03-22 19:16:34
【问题描述】:

我有以下代码处理一个事件两次。但是我总是想确保mynewclass 总是先处理事件,然后触发本地事件处理程序代码。我知道 MyClass 事件应该首先触发,因为它是第一个创建的,但是由于线程和排队正在发生,我认为它花费了太长时间并且在我希望它这样做之前它在 myhandleeventlocal 中做某事。有什么办法可以等待它发生?

    public MyMainClass
    {

    private MyMethod()
    {
        MyClass mynewclass = new MyClass();
        mynewclass.myObject += MyHandler(myhandleventlocal);
        mynewclass.loadedevent += EventHandler(loadedevent)
    }

    private void myhandleventlocal()
    {

             //do stuff

    }

    private void loadedevent()
    {
         //do some stuff
     }

    }

    public MyClass
    {
         public MyObject myObject;
         public event loadedevent;
         public MyClass()
         {
               myObject = new MyObject();
               myObject += MyHandler(myhandlevent);

         }

         private void myhandlevent(long value, string detail)
         {

             //Start a thread
             //Enqueue value and detail
             //On seperate thread dequeue value and process it
             //Raise loadedevent event

         }

    }

更新:我更新了我的问题和代码来演示问题。

【问题讨论】:

  • -1:您的代码无法编译。
  • 不应该!这是一个粗略的例子。

标签: c# .net .net-3.5 c#-3.0 event-handling


【解决方案1】:

默认事件处理程序是按照你添加它们的顺序调用的,所以如果你总是按照你希望它们触发的顺序添加处理程序,那么它应该可以工作。

来自 Jon Skeet 在events and delegates 上的文章:

[...] 额外的代表被添加到列表末尾和从列表末尾删除 [...]

注意:您可以通过更改事件上的addremove 操作来指定其他一些行为来覆盖事件的默认行为。然后,您可以将事件处理程序保存在您自己管理的列表中,并根据您喜欢的任何规则处理触发顺序。

【讨论】:

  • 虽然 Jon 是对的,但规范并没有指定触发顺序。虽然我不指望 MS 会改变游戏计划,但如果应用真的依赖于知道触发顺序,我们会通过实现事件的 addremove 元素来控制执行。
【解决方案2】:

如果您不能保证添加事件处理程序的顺序,只需为mynewclass 添加一个,然后在该代码中调用另一个代码。

【讨论】:

    【解决方案3】:

    由于事件处理程序是按照您添加它们的顺序调用的,根据我在您的问题中看到的代码,您不能首先调用 mynewclass 的处理程序。 MyClass 创建的事件处理程序总是首先添加。

    一种解决方案是控制事件处理程序的优先级。代替使用内置事件处理程序 +=/-= 运算符,您将拥有添加和删除事件的方法,您可以在其中显式指定排序。这样,如果一个类知道它需要首先处理事件,它可以要求这样。不过要小心,因为您很容易遇到多个类都坚持让他们先处理事件的情况。

    这里有一些快速而肮脏的代码可以帮助您入门:

    class MyClass {
        private LinkedList<MyEventHandler> eventHandlers;
        public enum Ordering { First, Last, ... };
        public void AddHandler(MyEventHandler handler, Ordering order) {
            switch(order) {
                case Ordering.First:
                    eventHandlers.AddFirst(handler);
                    break;
                // fill in other cases here...
            }
        }
        public void RaiseEvent() {
            // call handlers in order
            foreach(MyEventHandler handler in eventHandlers)
                eventHandler();
        }
    }
    

    【讨论】:

      【解决方案4】:

      参考siride解决方案,您还可以实现您的处理程序并以这种方式确定位置。比如颠倒顺序(总是在开头添加)或添加一些逻辑。

      【讨论】:

        猜你喜欢
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多