C # SmtpClient.Send () - Любая альтернатива (или компаньон) для обработки исключения?

2

(Долго читатель SO, первый раз задающий q.

Я новичок в С#, который был в мире PHP/Ruby/Python уже много лет, поэтому я приношу свои извинения, если это вопрос допинга.)

Я выполняю некоторое обслуживание старого приложения на С#, которое сбой, когда SmtpClient.Send() терпит неудачу. Из того, что я почерпнул из MSDN, я вижу очевидный способ исправить это, но мой вопрос также касается более общего случая.

В соответствии с MSDN:

  try {
          client.Send(message);
  }  
  catch (Exception ex) {
          Console.WriteLine("Exception caught in CreateTestMessage2(): {0}", 
                ex.ToString() );
  }

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

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

Снова, извините, если это вопрос дерьма. Я попытался найти SO и Google, насколько мог.

EDIT: я только что нашел этот вопрос Рекомендации по управлению исключениями в java или C  которые вполне могут пойти, чтобы ответить на мой вопрос.

EDIT2: Спасибо за оперативную обратную связь, невероятно быстро. Я уже много думал об этой проблеме и, возможно, это могло бы уточнить то, что я прошу.

Можно ли сказать, что некоторых исключений, таких как SmtpException, действительно нельзя избежать? Правильнее ли говорить о том, что правильный стиль использует исключения, такие как SmtpException, чтобы сказать вам, что что-то пошло не так с передачей, и вы просто обрабатываете его, как бы вы хотели?

Я чувствую, что в этом вопросе я немного тускнею, но я спрашиваю, потому что все, что я могу узнать, полезно для моей уверенности.

  • 1
    Не зная, что за исключение (я), трудно ответить на ваш вопрос. Похоже, есть 6 различных исключений, которые могут быть выброшены. Вы можете проверить свой ввод, чтобы предотвратить каждый возможный тип, или отловить только те, которые вы можете обработать.
Теги:
exception

5 ответов

3
Лучший ответ

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

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

Мой общий совет: поймайте определенные исключения как можно ближе к источнику, пусть все остальное забьет стек и запустит его в том месте, где у вас достаточно контекста, чтобы позже попытаться воспроизвести исключение. Будьте осторожны, что ловли, а затем повторное бросание дорого; сценарий в вашем примере, где вы, возможно, захотите сделать это, будет, если, скажем, SmtpException был таймаутом соединения (я делаю это), тогда одна стратегия может быть экспоненциальной отступлением и повторять до n раз с момента отправки сервер может быть опущен, а затем, наконец, сдаться и реконструировать, если вам это не удалось.

На самом деле короткий ответ: "Все зависит".

  • 0
    Действительно хороший обзор, спасибо.
4

Это хороший пример того, что я называю "экзогенной" ситуацией исключения.

http://ericlippert.com/2008/09/10/vexing-exceptions/

Рассмотрим аналогичный случай - открытие файла. Вы можете уменьшить вероятность получения исключения:

  • проверка наличия файла
  • проверка наличия у пользователя разрешения на открытие файла
  • проверка того, заблокировала ли другое приложение файл
  • л
  • бла-бла
  • бла-бла-бла

Вы можете сделать все это, а STILL получить исключение при открытии файла. Поскольку между выполнением всех этих проверок и попыткой открыть файл, что-то могло измениться. Другой процесс, возможно, изменил разрешения или заблокировал файл, или пользователь удалил CD-ROM с диска или что-то еще. Является ли действие успешным или нет, основано на экзогенном, реальном состоянии, которое вы не можете проверить каким-либо гарантированным способом.

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

Отправка почты осуществляется одинаково. Вы можете проверить всевозможные вещи, чтобы попытаться устранить исключение, которое, вероятно, будет работать в 99% случаев, но вы по-прежнему не можете ГАРАНТИРОВАТЬ, что между всеми вашими чеками и фактической попыткой отправить почту, что кто-то не отключил маршрутизатор в точно неправильный момент. Вам просто придется всасывать его и обрабатывать исключения.

  • 0
    Ха-ха, я действительно должен научиться возвращаться и проверять свои старые вопросы. Я никогда не ожидал получить ответ от самого Эрика! Спасибо за ответ. С тех пор я проделал чертовски много работы в .NET (в настоящее время борюсь с EF4, MVC2 и WCF, ням-ням), и оглядываясь назад на этот вопрос, заставил меня улыбнуться.
1

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

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

1

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

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню