Когда именно события выполняются в C #? - PullRequest
11 голосов
/ 18 мая 2011

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

Как именно обрабатываются события в C #? Если событие инициировано, будет ли (a) часть кода, прикрепленная к этому событию, выполняться немедленно ? Или событие (b) будет помещено в стек событий и будет выполняться всякий раз, когда .NET сочтет его подходящим для выполнения, в то время как другой код выполняется за это время?

Ответы [ 6 ]

12 голосов
/ 18 мая 2011

Если событие возникает, будет ли часть кода, прикрепленная к этому событию, выполняться немедленно?

Ну да и нет.События являются многоадресными делегатами, поэтому к событию может быть привязано ноль, одна или несколько «частей кода».В сценарии, где их много, ясно, что один из них должен идти первым, а один - вторым.Тот, который идет вторым, не выполняется сразу после возникновения события;оно выполняется сразу же после того, как первый обработчик событий завершится нормально.

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

Предположим, ваше приложение плохо написано и в нем висит пользовательский интерфейс.Пока пользовательский интерфейс завис, пользователь нажимает кнопку 1 и кнопку 2. Поскольку приложение зависает, ничего видимого не происходит.События для кнопки 1 и кнопки 2, которые были нажаты, не запускаются.Но Windows создала очередь сообщений и включила в нее тот факт, что кнопка 1 и кнопка 2 имеют ожидающие щелчки, которые необходимо обработать, когда приложение самоизменяется.Когда цикл сообщений прокачивается, срабатывает событие нажатия кнопки 1.Когда он завершает свою работу, цикл сообщений перекачивается снова и запускается событие нажатия кнопки 2.

Так что да, в этом смысле события помещаются в очередь и выполняются позже, но это не так, когда .NETсчитает это подходящим ";это когда поток, который обрабатывает очередь сообщений, снова начинает обрабатывать очередь сообщений.Здесь нет таинственной политики Windows, управляющей вашим кодом.

8 голосов
/ 18 мая 2011

Это полностью зависит от кода повышения (и подписки) события.

Если вы вызываете событие следующим образом:

EventHandler handler = MyEvent;

if (handler != null)
{
    handler(this, EventArgs.Empty);
}

или что-то подобное, тогда все обработчики событийбудет выполнен немедленно.Это типичная реализация ... вам нужно потрудиться, чтобы поместить каждого делегата события в очередь сообщений WinForms или что-то в этом роде.

Если бы вы могли дать нам больше информации о том, какие событияВы говорите о том, как они реализованы, и мы можем помочь вам больше.

Для получения дополнительной информации о событиях и делегатах (и разнице между ними) вы можете прочитать myстатья на тему .

5 голосов
/ 18 мая 2011

C # события, как и остальные делегаты, выполняются немедленно при запуске.

2 голосов
/ 18 мая 2011

Если явно не реализовано иное, события вызываются синхронно.

Обычно код, запускающий событие, выглядит так:

public event EventHandler MyEvent;

protected virtual void OnMyEvent()
{
    EventHandler handler = MyEvent; // keep a copy to avoid race conditions
    if (handler != null)
        handler(this, EventArgs.Empty);
}

Как видно из этого кода, обработчики событий вызываются немедленно и синхронно из метода OnMyEvent.

1 голос
/ 18 мая 2011

Я полагаю, что на ваш вопрос здесь ответили:

Обработчики событий обрабатываются асинхронно?

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

0 голосов
/ 18 мая 2011

Как указывалось в предыдущем awnser, это полностью зависит от кода, который вызывает событие или обрабатывает событие.

Чего не хватает в приведенных выше примерах, так это кода того, как вызывать / обрабатывать события. Я знаю, что это просто быстрые примеры, но, тем не менее, важна хорошая практика.

Если вам нужны хорошие примеры / материалы о том, как правильно обрабатывать события в C #, вы можете взглянуть на эту статью: http://www.codeproject.com/KB/cs/event_fundamentals.aspx

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