Приоритизация обработчиков событий - PullRequest
2 голосов
/ 29 июля 2010

У меня есть следующий код, где я обрабатываю событие дважды.Однако я всегда хочу убедиться, что 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

         }

    }

ОБНОВЛЕНИЕ: Я обновил свой вопрос и код, чтобы продемонстрировать проблему.

Ответы [ 4 ]

6 голосов
/ 29 июля 2010

По по умолчанию обработчики событий вызываются в том порядке, в котором вы их добавили, поэтому, если вы всегда добавляете обработчики в том порядке, в котором вы хотите, чтобы они запускались, это должно работать.

Из статьи Джона Скита о событиях и делегатах :

[...] дополнительные делегаты добавляются в конец списка и удаляются из него [...]

Примечание: Вы можете переопределить поведение событий по умолчанию, изменив операции add и remove для вашего события, чтобы указать другое поведение. Затем вы можете хранить свои обработчики событий в списке, которым вы управляете сами, и обрабатывать порядок запуска на основе любых правил, которые вам нравятся.

3 голосов
/ 29 июля 2010

Если вы не можете гарантировать порядок добавления обработчиков событий, просто добавьте один для mynewclass, а затем в этом коде вызовите другой код.

2 голосов
/ 29 июля 2010

Поскольку обработчики событий вызываются в том порядке, в котором вы их добавляете, основываясь на коде, который я вижу в вашем вопросе, вы не можете сделать так, чтобы обработчик 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();
    }
}
0 голосов
/ 29 июля 2010

Обращаясь к решению siride, вы также можете реализовать свои обработчики и решить положение таким образом.Как инвертирование порядка (всегда добавляйте в начале) или добавьте немного логики.

...