Когда точно выполняются события на С#?
Я разработал приложение С#, которое активно использует события. Теперь это приложение иногда делает забавные вещи, которые я не могу понять или отслеживать по определенной причине, почему они должны произойти. Я считаю, что причиной этих прерывистых сбоев является какое-то concurrency или состояние гонки, которое я не ожидал.
Как точно обрабатываются события на С#? Если событие поднято, будет ли (а) часть кода, прикрепленная к этому событию, немедленно выполнить? Или событие (б) будет помещено в стек событий и будет выполняться всякий раз, когда .NET считает, что он подходит для выполнения, пока выполняется другой код?
Ответы
Ответ 1
Если возникает событие, будет ли выполняться часть кода, прикрепленная к этому событию?
Хорошо, да и нет. События - это многоадресные делегаты, поэтому может быть ноль, одна или несколько "частей кода", связанных с событием. В сценарии, где их много, очевидно, один из них должен идти первым, и один из них должен пройти второй. Тот, который идет вторым, не выполняется сразу после поднятого события; он выполняется сразу после завершения первого обработчика событий.
будет ли событие помещено в стек событий и будет выполняться всякий раз, когда .NET считает его подходящим для выполнения, пока выполняется другой код?
Предположим, что ваше приложение плохо написано и висит в пользовательском интерфейсе. Пока пользовательский интерфейс висит, пользователь нажимает кнопку 1 и кнопку 2. Поскольку приложение висит, ничего не происходит. События для нажатия кнопки 1 и кнопки 2 не срабатывают. Но Windows создала очередь сообщений и указала на нее тот факт, что кнопка 1 и кнопка 2 имеют ожидающие клики, которые необходимо обработать, когда приложение распадается. Когда цикл сообщения перекачивается, срабатывает кнопка "1 щелчок". Когда все будет сделано, цикл сообщения снова перекачивается, и кнопка "click click click" запускается.
Итак, да, в этом случае события помещаются в очередь и выполняются позже, но это не "когда .NET считает это подходящим"; когда поток, который обрабатывает очередь сообщений, снова обрабатывает очередь сообщений. Там нет таинственной политики Windows, контролирующей ваш код.
Ответ 2
Это полностью зависит от кода повышения (и подписки) события.
Если вы поднимаете событие следующим образом:
EventHandler handler = MyEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
или что-то подобное, тогда все обработчики событий будут выполнены немедленно. Это типичная реализация... вам нужно работать немного сложнее, чтобы добавить делегат каждого события в очередь сообщений WinForms или что-то в этом роде.
Если вы могли бы предоставить нам больше информации о том, какие события вы говорите и как они реализованы, мы можем помочь вам больше.
Для получения дополнительной информации о событиях и делегатах (и о различии между ними) вы можете прочитать мою статью по теме.
Ответ 3
События С#, как и остальные делегаты, выполняются сразу же при срабатывании.
Ответ 4
Если явно не реализовано иначе, события называются синхронно.
Обычно код, запускающий событие, выглядит следующим образом:
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
.
Ответ 5
Я верю, что на ваш вопрос был дан ответ:
Обработаны ли обработчики событий асинхронно?
Короче говоря, это зависит от вашей реализации, но обработка событий по умолчанию обрабатывается синхронно. Однако есть способы сделать его асинхронным.
Ответ 6
Как указано в предыдущем тэссе, он полностью зависит от кода, который поднимает событие или обрабатывает событие.
Что не хватает приведенным выше примерам, является правильным кодом для того, как поднимать/обрабатывать события. Я знаю, что они просто быстрые примеры, но, тем не менее, важна хорошая практика.
Если вам нужны хорошие примеры/материалы о том, как события могут быть правильно обработаны на С#, вы можете взглянуть на эту статью: http://www.codeproject.com/KB/cs/event_fundamentals.aspx