Должны ли обработчики событий C # быть безопасными для исключений? - PullRequest
20 голосов
/ 24 февраля 2010

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

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

Ответы [ 6 ]

12 голосов
/ 24 февраля 2010

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

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

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

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

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

9 голосов
/ 24 февраля 2010

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

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

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

5 голосов
/ 24 февраля 2010

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

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

3 голосов
/ 24 февраля 2010

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

2 голосов
/ 24 февраля 2010

Это заманчиво, но в конечном итоге все зависит от ситуации.

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

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

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

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