Предполагая, что одно событие имеет несколько обработчиков, если какой-либо из обработчиков событий генерирует исключение, остальные обработчики не выполняются.
Означает ли это, что обработчики событий никогда не должны бросать?
Предполагая, что одно событие имеет несколько обработчиков, если какой-либо из обработчиков событий генерирует исключение, остальные обработчики не выполняются.
Означает ли это, что обработчики событий никогда не должны бросать?
Так как вызов события означает, что вызывающий абонент не знает о вызываемом абоненте:
Вызов обработчика событий должен быть надежным перед лицом произвольных исключений. Все, что нужно для стека вызовов, должно правильно очищать свой беспорядок, если произойдет что-то совершенно неожиданное.
Обработчики событий должны действительно избегать исключения исключений.
Такие вещи, как нулевые ссылочные исключения, действительно непростительны в любом коде, поэтому, очевидно, нас это не беспокоит.
Такие вещи, как исключения файлов IO, всегда могут возникать при записи или чтении файла, поэтому я бы избегал делать IO внутри обработчика событий. Если имеет смысл делать IO в обработчике событий, то это также заставляет senst обрабатывать исключения IO внутри обработчика. Не передавайте это обратно вызывающему. Найдите способ справиться с этим.
В идеальном мире, да. Это хорошая идея, чтобы попытаться спроектировать обработчики событий, чтобы они:
Невыполнение этого приведет к неожиданным побочным эффектам, поскольку другие подписчики события никогда не смогут получать сообщения или получать их очень поздно.
Вы НЕ должны проглатывать исключения в обработчике событий, но я бы вообще не рекомендовал их бросать. Проблема заключается в том, что в целом нет хорошего места для исключения исключений, вызванных обработчиками событий.
Структура дизайна обработчиков событий приводит к некоторым потенциальным проблемам, поскольку они оба косвенно вызываются и могут быть многоадресными. Поскольку они косвенны, вы должны быть осторожны и планировать, где вы можете поймать исключения, которые они могут бросить. Поскольку они являются многоадресными, исключение в обработчике может привести к тому, что другой обработчик никогда не получит событие.
Почему обработчики событий не похожи на другие шаблоны? Какая разница? Исключение означает, что подпрограмма сообщает вызывающему, что она не может работать так, как она предназначена для работы. Это означает, что вызывающий должен что-то с этим сделать. Если обработчик выполняет некоторую обработку, жизненно важную для прецедента, тогда разумно, что когда она раздавливается, остальная часть программы должна останавливаться.
Заманчиво это делать, но в конечном итоге это зависит от ситуации.
В приложении ASP.NET я просто позволяю обработчикам событий исключать исключения. Эти исключения затем позволят работать с пользовательскими функциями страницы ASP.NET.
В настольном приложении я всегда добавляю блок try/catch/finally вокруг кишки любого обработчика события. Таким образом, любые исключения всегда регистрируются и отображаются конечным пользователям, но никогда не выходят из обработчика событий, поэтому они не вызывают сбои приложения.