Должен ли я всегда оборачивать вызовы внешних ресурсов в try-catch? (т.е. обращения к базе данных или файловой системе) Существует ли наилучшая практика обработки ошибок при вызове внешних ресурсов?
всегда пытаться перехватывать вызовы внешних ресурсов?
Ответы (6)
Перехватывайте только исключения, которые вы можете обработать. Так, например, при использовании внешних ресурсов лучше всего перехватывать конкретные исключения, которые, как вы знаете, вы можете обработать. В случае файлов это может быть (IOException, SecurityException и т. д.), в случае базы данных исключение может быть SqlException или другое.
В любом случае не перехватывайте исключения, которые вы не обрабатываете, пусть они передаются на верхний уровень, который может это сделать. Или, если по какой-то причине вы перехватываете исключения, но не обрабатываете их, перегенерируйте их, просто используя throw; (что создаст операцию повторной генерации IL, а не trow).
В случае использования ресурсов, которые вы не знаете, какой тип исключений может генерироваться, вы как бы вынуждены перехватывать общий тип исключения. И в этом случае безопаснее было бы использовать указанные ресурсы из другого домена приложения (если это возможно) или позволить исключению подняться на верхний уровень (бывший пользовательский интерфейс), где они могут отображаться или регистрироваться.
Я думаю, что есть три причины иметь блок catch:
- Вы можете обработать исключение и восстановить (из кода «низкого уровня»)
- Вы хотите переписать исключение (опять же, из кода «низкого уровня»)
- Вы находитесь на вершине стека, и хотя вы не можете восстановить саму операцию, вы не хотите, чтобы все приложение отключилось.
Если вы придерживаетесь их, у вас должно быть очень мало блоков catch по сравнению с блоками try/finally
, а эти блоки try/finally
почти всегда просто вызывают Dispose
, и поэтому их лучше всего записывать в виде операторов using
.
Итог: очень важно иметь блок finally
для освобождения ресурсов, но блоки catch
обычно должны встречаться реже.
Это то, что я нашел, и это имеет смысл для меня. Проверьте вручную очевидные вещи, пусть try-catch сделает все остальное.
У Эрика Липперта есть хороший блог на эту тему: здесь .
Нет никакого смысла (кроме того, чтобы раздражать (см. Блог)) ловить исключение, если вы не можете сделать что-то полезное; и в большинстве случаев вы просто не можете - так что пусть это пузырится (ваш пользовательский интерфейс, очевидно, должен что-то очищать и отображать).
Однако вы можете попробовать/наконец разобраться с управлением ресурсами. Или даже чище, используя блок, чтобы сделать то же самое.
Я думаю, что абсолютный ответ полностью условен (как вы контролируете среду, каков ожидаемый баланс между производительностью и согласованностью и многое другое, я уверен), но в целом я всегда так делаю, предпочитая безопасность потенциально более медленному производительность.
это всегда зависит от того, чего вы хотите достичь. Сервер, который не отвечает, может быть достаточно серьезным, чтобы остановить все, что делает подпрограмма, и исключение должно быть выдано вызывающему.
В других случаях вам все равно, не удалось ли вам обновить базу данных или нет. Тогда использование исключения в порядке.
Очевидно, вы не хотите показывать трассировку стека конечному пользователю, поэтому вам нужно где-то ее перехватить.