всегда пытаться перехватывать вызовы внешних ресурсов?

Должен ли я всегда оборачивать вызовы внешних ресурсов в try-catch? (т.е. обращения к базе данных или файловой системе) Существует ли наилучшая практика обработки ошибок при вызове внешних ресурсов?


person Aaron Palmer    schedule 24.10.2008    source источник


Ответы (6)


Перехватывайте только исключения, которые вы можете обработать. Так, например, при использовании внешних ресурсов лучше всего перехватывать конкретные исключения, которые, как вы знаете, вы можете обработать. В случае файлов это может быть (IOException, SecurityException и т. д.), в случае базы данных исключение может быть SqlException или другое.

В любом случае не перехватывайте исключения, которые вы не обрабатываете, пусть они передаются на верхний уровень, который может это сделать. Или, если по какой-то причине вы перехватываете исключения, но не обрабатываете их, перегенерируйте их, просто используя throw; (что создаст операцию повторной генерации IL, а не trow).

В случае использования ресурсов, которые вы не знаете, какой тип исключений может генерироваться, вы как бы вынуждены перехватывать общий тип исключения. И в этом случае безопаснее было бы использовать указанные ресурсы из другого домена приложения (если это возможно) или позволить исключению подняться на верхний уровень (бывший пользовательский интерфейс), где они могут отображаться или регистрироваться.

person Pop Catalin    schedule 24.10.2008

Я думаю, что есть три причины иметь блок catch:

  • Вы можете обработать исключение и восстановить (из кода «низкого уровня»)
  • Вы хотите переписать исключение (опять же, из кода «низкого уровня»)
  • Вы находитесь на вершине стека, и хотя вы не можете восстановить саму операцию, вы не хотите, чтобы все приложение отключилось.

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

Итог: очень важно иметь блок finally для освобождения ресурсов, но блоки catch обычно должны встречаться реже.

person Jon Skeet    schedule 24.10.2008


У Эрика Липперта есть хороший блог на эту тему: здесь .

Нет никакого смысла (кроме того, чтобы раздражать (см. Блог)) ловить исключение, если вы не можете сделать что-то полезное; и в большинстве случаев вы просто не можете - так что пусть это пузырится (ваш пользовательский интерфейс, очевидно, должен что-то очищать и отображать).

Однако вы можете попробовать/наконец разобраться с управлением ресурсами. Или даже чище, используя блок, чтобы сделать то же самое.

person Marc Gravell    schedule 24.10.2008

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

person Timothy Carter    schedule 24.10.2008

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

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

Очевидно, вы не хотите показывать трассировку стека конечному пользователю, поэтому вам нужно где-то ее перехватить.

person Luk    schedule 24.10.2008