управляемые событиями методы и последовательность выполнения в c # .NET - PullRequest
0 голосов
/ 26 октября 2011

Гипотетически говоря, если бы у меня было два метода (обработчика событий), управляемых одним и тем же событием, какой метод выполняется первым?

Пример:

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

Что называется первым?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 26 октября 2011

Это зависит от издателя события, но обычно будет зависеть от того, какой обработчик был добавлен к событию первым. Это реализация по умолчанию для события, которое в основном реализуется с использованием делегата. Так, например:

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

Это определенно вызовет FirstHandler до SecondHandler. Однако нет никакой гарантии, что событие будет реализовано только с использованием таких делегатов.

РЕДАКТИРОВАТЬ: в то время как поведение обработки событий зависит от издателя событий, часть комбинации делегатов точно указана в спецификации языка C #, раздел 7.8.4:

[...] В противном случае результатом операции является новый экземпляр делегата, который при вызове вызывает первый операнд, а затем вызывает второй операнд.

Метод BCL Delegate.Combine дает аналогичную гарантию (выделено мной):

(Возвращаемое значение) Новый делегат со списком вызовов, который объединяет списки вызовов a и b в указанном порядке . Возвращает a, если b равно нулю, возвращает b, если a является нулевой ссылкой, и возвращает нулевую ссылку, если a и b являются нулевыми ссылками.

1 голос
/ 26 октября 2011

Реализация по умолчанию будет вызывать обработчики событий в том порядке, в котором они были добавлены, однако можно настроить это поведение.Если поведение настроено, клиент не может сказать это.Таким образом, реальный ответ на ваш вопрос заключается в том, что порядок, в котором создаются обработчики событий, «зависит» и может даже измениться во время выполнения, однако подавляющее большинство событий имеют реализацию по умолчанию.

Например:

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

1 голос
/ 26 октября 2011

Первый подписался один. "Первый пришел - первый обслужен".

0 голосов
/ 26 октября 2011

Нет способа определить, какой обработчик события будет вызван первым.Многие люди думают, что первый, кто подпишется, будет вызван первым (как это обычно бывает), но не указан CLI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...