Подтвердить что ты не робот

Какие исключения я не должен улавливать?

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

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

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

Спасибо!

Изменить: Чтобы немного разобраться, вот основная структура моей программы

foreach(var item in longItemList)
{
   try
   {
      bigDynamicDispatchMethod(item);
   }
   catch(Exception ex)
   {
      logException(ex);
   }
}

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

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

Есть ли лучший способ структурировать мое приложение, чтобы справиться с этим? Я открыт для предложений.

4b9b3361

Ответ 1

Вам не нужен список "плохих" исключений, вы должны относиться ко всему так же плохо по умолчанию. Только поймите, с чем вы можете справиться и восстановиться. CLR может уведомлять о необработанных исключениях, чтобы вы может вести их надлежащим образом. Проглатывание всего, кроме черных перечисленных исключений, не является правильным способом исправить ошибки. Это просто замаскировало их. Прочитайте this и this.

Не исключайте особых исключений при ловле с целью передачи исключений.

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

public class BadExceptionHandlingExample2 {
    public void DoWork() {
        // Do some work that might throw exceptions.
    }
    public void MethodWithBadHandler() {
        try {
            DoWork();
        } catch (Exception e) {
            if (e is StackOverflowException ||
                e is OutOfMemoryException)
                throw;
            // Handle the exception and
            // continue executing.
        }
    }
}

Несколько других правил:

Избегайте обработки ошибок путем улавливания неспецифических исключений, таких как System.Exception, System.SystemException и т.д., В приложении код. Бывают случаи, когда обработка ошибок в приложениях допустимы, но такие случаи встречаются редко.

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

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

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

Эрик Липперт классифицирует все исключения на 4 группы: Fatal, "Boneheaded", Vexing, Exogenous. Ниже приводится моя интерпретация совета Эрика:

  Exc. type | What to do                          | Example
------------|-------------------------------------|-------------------
Fatal       | nothing, let CLR handle it          | OutOfMemoryException
------------|-------------------------------------|-------------------
Boneheaded  | fix the bug that caused exception   | ArgumentNullException
------------|-------------------------------------|-------------------
Vexing      | fix the bug that caused exception   | FormatException from 
            | (by catching exception  because     | Guid constructor
            | the framework provides no other way | (fixed in .NET 4.0 
            | way of handling). Open MS Connect   | by Guid.TryParse)
            | issue.                              | 
------------|-------------------------------------|-------------------
Exogenous   | handle exception programmatically   | FileNotFoundException 

Это примерно эквивалентно Microsoft категоризация: использование, ошибка программы и сбой системы. Вы также можете использовать инструменты статического анализа, такие как FxCop, чтобы обеспечить некоторые из этих правила.

Ответ 2

Не поймите никаких исключений, которые вы не знаете, как безопасно обращаться.

Захват Exception является особенно плохой практикой, единственное хуже - catch, который не указывает какой-либо управляемый тип исключения (поскольку он также поймал бы не управляемые исключения).

Ответ 3

Более правильный дизайн будет поддерживаться вопросом: Какие исключения я должен уловить?

Если вам действительно нужно поймать все и все исключения и все равно продолжать, то вы должны использовать как AppDomain, так и отдельные рабочие процессы. Или измените свой хост на ASP.NET или планировщик задач, которые уже выполнили всю сложную работу по изоляции процессов и повторным попыткам.

Ответ 4

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

Ответ 5

Я хотел бы обратиться к совету из следующей статьи.

Правила разработки правил .NET Framework: не допускайте исключения, которые Вы не можете обращаться

http://www.codeproject.com/KB/cs/csmverrorhandling.aspx

Также из ссылки:

Вы никогда не должны улавливать System.Exception или System.SystemException в блок catch

Ответ 6

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

  • Прочтите из передовых методов обработки переходов msdn google.
  • Никогда не поймите с неспецифическими исключениями, такими как Exception