Подтвердить что ты не робот

Должны ли обработчики событий С# быть безопасными?

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

Означает ли это, что обработчики событий никогда не должны бросать?

4b9b3361

Ответ 1

Так как вызов события означает, что вызывающий абонент не знает о вызываемом абоненте:

  • Вызов обработчика событий должен быть надежным перед лицом произвольных исключений. Все, что нужно для стека вызовов, должно правильно очищать свой беспорядок, если произойдет что-то совершенно неожиданное.

  • Обработчики событий должны действительно избегать исключения исключений.

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

Такие вещи, как исключения файлов IO, всегда могут возникать при записи или чтении файла, поэтому я бы избегал делать IO внутри обработчика событий. Если имеет смысл делать IO в обработчике событий, то это также заставляет senst обрабатывать исключения IO внутри обработчика. Не передавайте это обратно вызывающему. Найдите способ справиться с этим.

Ответ 2

В идеальном мире, да. Это хорошая идея, чтобы попытаться спроектировать обработчики событий, чтобы они:

  • Не бросайте исключения
  • Выполнение очень быстро

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

Ответ 3

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

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

Ответ 4

Почему обработчики событий не похожи на другие шаблоны? Какая разница? Исключение означает, что подпрограмма сообщает вызывающему, что она не может работать так, как она предназначена для работы. Это означает, что вызывающий должен что-то с этим сделать. Если обработчик выполняет некоторую обработку, жизненно важную для прецедента, тогда разумно, что когда она раздавливается, остальная часть программы должна останавливаться.

Ответ 5

Заманчиво это делать, но в конечном итоге это зависит от ситуации.

  • Если вы хотите, чтобы программа выходила из строя, а не запускала риск работы в плохом или странном состоянии, то обязательно исключите исключение.
  • Если вы ДЕЙСТВИТЕЛЬНО не заботитесь (подумайте об этом), и вам нужно только отметить исключение, тогда упаковка в блоки try/catch имеет смысл.
  • Если вы хотите, чтобы все обработчики событий имели возможность запускать перед сбоем (например, возможно, некоторые из обработчиков выделяют ресурсы), тогда требуется немного больше усилий...

Ответ 6

В приложении ASP.NET я просто позволяю обработчикам событий исключать исключения. Эти исключения затем позволят работать с пользовательскими функциями страницы ASP.NET.

В настольном приложении я всегда добавляю блок try/catch/finally вокруг кишки любого обработчика события. Таким образом, любые исключения всегда регистрируются и отображаются конечным пользователям, но никогда не выходят из обработчика событий, поэтому они не вызывают сбои приложения.