Есть ли какая-то польза от "броска" в уловке?
Имея "горячую дискуссию" с коллегой о своей практике обертывания большей части своих функций в попытке/уловке, но уловка имеет JUST "бросок" в нем, например.
Private sub foo()
try
'Do something'
catch
throw 'And nothing else!'
End Try
End Sub
Моя мысль заключалась в том, чтобы даже не беспокоиться (предполагая, что вам не нужно ничего делать в этот момент) - исключение превратилось бы в следующий обработчик исключений в родительском члене.
Единственный аргумент, который звучал правдоподобно, заключался в том, что иногда исключения не были пойманы, а ваш код остановлен (в режиме отладки) с текущей строкой, выделенной зеленым цветом... и что это может быть связано с несколькими потоками?
Лучшая практика устанавливает "обработчик исключения для каждого потока", но в основном мы работаем с однопоточными.
Хорошо, что может быть полезно в режиме отладки не внезапно выскочить к родительскому члену (да, Joel!) - вы перейдете в инструкцию "throw" и сможете исследовать своих локальных жителей.
Но тогда ваш код будет "замусорен с помощью try/catch/throws" (чтобы процитировать здесь еще один поток)?
И какие бы накладные расходы были связаны с добавлением try/catch/throws во всех случаях, если не возникает исключение (например, если вы избегаете попыток/улов в жестких циклах)?
Ответы
Ответ 1
Причина, по которой у вас есть одиночный бросок внутри catch, а не бросание нового исключения, заключается в том, что это приводит к сохранению исходных данных трассировки стека/исключений. И одна из причин, почему вы можете это сделать, - это то, что теперь вы можете установить там точку прерывания для отладки.
Ответ 2
Корпорация Майкрософт рекомендует не перехватывать исключение, когда единственное, что вы делаете, - это немедленно его восстановить (я не помню источник на данный момент).
В вашем коде должны появляться исключения, которые вы хотите обработать для очистки вещей или подобных действий.
Таким образом, как правило, это не хорошая практика, чтобы ловить и реконструировать исключение.
Причины ловить и заменить его другим исключением могут быть
- Вход
- Скрытие конфиденциальной информации от вызывающего (Stacktrace, сведения об исключении)
И для отладки вы можете захотеть изменить свой "разрыв, когда исключение:" - обработчик (нажмите Ctrl + Alt + e) значение "брошено" на выбранные исключения CLR.
Возможно, вы захотите взглянуть на блок обработчика исключений entlib (EHB), с помощью которого вы можете установить шаблон о том, как справляться с исключениями в вашем коде.
Что касается вашего вопроса о производительности, я думаю, что это не проблема, чтобы иметь много блоков try/catch в вашем коде, но вы получите хиты производительности, когда ваш код поднимает и ловит многие исключения.
Ответ 3
Я только когда-нибудь сделаю это при отладке проблемы, и я снова удалю код перед проверкой. Иногда бывает удобно поставить точку останова для остановки на определенном уровне стека, если будет выбрано исключение. Кроме того, хотя - нет.
Ответ 4
На практике моя мысль заключается в том, что если вы не собираетесь обрабатывать эту ошибку, не поймите ее.
Ответ 5
Один из последствий использования улова и немедленного восстановления - это то, что любые внутренние "окончательные" блоки будут выполняться до появления "Catch" (что, в свою очередь, будет до распространения исключения). Это актуально в двух сценариях:
- Если исключение в конечном счете необработано, возможно, что ловушка необработанного исключения может выйти из приложения без каких-либо "окончательных" блоков. Выполнение улова и немедленное ретронирование гарантируют, что все "окончательные" блоки в улове будут выполняться, даже если исключение в конечном итоге будет необработанным.
- Возможно, код на vb.net и, возможно, на других языках, будет действовать на исключение, прежде чем будут запущены какие-либо окончательные блоки. Использование блока "try" с catch-and-instant-rethrow приведет к тому, что блоки "finally" в этом блоке catch будут выполняться до того, как любые внешние блоки "try" получат первый взгляд на исключение.
Дополнительная оговорка с уловкой и немедленным восстановлением: по какой-то причине улов и немедленный ретроуз приведет к удалению номера строки трассировки стека для вызова функции, вызвавшего исключение. Я не знаю, почему в этом случае текущая запись функции в трассировке стека не может быть оставлена в одиночестве, но это не так. Если вы не используете файл .pdb для получения информации о номере линии, это не проблема, но если вы хотите использовать такую информацию, это может раздражать.
Как правило, упомянутые выше эффекты нежелательны, но бывают случаи, когда один или оба из первых двух эффектов могут быть полезными, а третий - допустимый. В этих случаях улов с немедленным восстановлением может быть уместным, хотя причина этого должна быть задокументирована.
Ответ 6
Выполнение этого всегда по умолчанию выглядит плохой дизайн. Но могут быть причины для ловли и метания, например, вы хотите бросить другое исключение.
Ответ 7
Да, это удобно для установки точки останова в catch.
альтернативный и более чистый способ - это точка останова в конструкторе объекта, который вы бросаете. Вы видите состояние программы в точке, ближе к источнику ошибки.
Ответ 8
Вам нужно not использовать предложение catch для исключения исключений в отладчике Visual Studio. Выберите Debug > Исключения и выберите, какие исключения вы хотите уловить, при необходимости все они.
Ответ 9
Если вы поймаете исключение и замените его другим исключением, вы обычно должны обернуть исходное исключение в новом. Обычно это делается путем передачи старого исключения в новый конструктор. Таким образом, вы можете выкопать столько, сколько необходимо, чтобы выяснить, что произошло. Основной случай, когда вы этого не сделали, - это когда вам нужно скрыть данные по соображениям безопасности. В этих случаях вы должны попытаться зарегистрировать данные об исключении, прежде чем очистить его.
Обоснование, которое я видел для обертывания исключений с помощью новых, вместо того, чтобы просто дать им пузыриться в стеке, заключается в том, что исключения должны быть на том же уровне, что и методы, из которых они исходят. Если я вызываю AuthenticateUser, я не хочу видеть исключение SQL. Вместо этого я должен увидеть какое-то исключение, чье имя говорит мне, что задача аутентификации не может быть завершена. Если я выкопаю в это исключение внутренние исключения, я мог бы затем найти исключение SQL. Лично я все еще взвешиваю плюсы и минусы этого.
Ответ 10
Поскольку обработка ошибок равна нулю, этот улов бесполезен. Если бы была регистрация или какая-то очистка, конечно, но в этой ситуации я бы избавился от try/catch.
Ответ 11
Это также может быть полезно, если вам нужно проверить что-то об исключении и сделать что-то для одного обстоятельства или выбросить его для других обстоятельств. Например, если вам нужно проверить номер ошибки в SQLException. Вы можете выполнить определенное действие, если номер ошибки - тот, который вы готовы обработать. Для других вы можете просто "бросить" его так, чтобы трассировка стека сохранялась, как упоминалось выше.