Как часто я должен использовать try и catch в С#?

При написании приложения С#, чей приоритет # 1 для никогда не сбой, как часто я должен использовать блок try-catch?

Можно ли инкапсулировать все утверждения в методе в блоках try-catch?

public void SomeMethod()
{
    try
    {
        // entire contents of the function
        // library calls
        // function calls
        // variable initialization .. etc
    }
    catch (Exception e)
    {
        // recover
    }
}

Каковы недостатки для обертывания всего в блоки try-catch?

Ответ 1

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

Кроме того, вы не хотите использовать try/catch для потока управления. Рассмотрим этот (плохой код):

try {

    FileStream fs = File.Open("somefile.txt", FileMode.Open);

} catch (Exception ex) {
    MessageBox.Show("The file does not exist. Please select another file");
}

Вы получите больше производительности от некоторых вещей, таких как File.Exists. например:

if(!File.Exists("somefile.txt"))
  MessageBox.Show("The file does not exist.")

EDIT: нашел прямую цитату MSDN:

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

Ответ 2

Это большая тема. Начните здесь за отличное обсуждение передовой практики обработки исключений и подготовиться к религиозной войне...

Блог команды анализа кода

Martin Fowler - Fail Fast

MSDN при обработке исключений

Проверено и отменено исключение

Мое собственное мнение состоит в том, что по большей части вы часто используете "try/finally", но "поймаете" очень мало. Проблема в том, что если вы попытаетесь поймать и обработать Исключения в неправильных экземплярах, вы можете случайно помещать свое приложение в плохое состояние. Как правило, используйте dev и test, чтобы узнать, где вам действительно нужно обрабатывать исключение. Это будут места, которые вы не можете проверить. т.е. вам не нужно действительно обращаться с noureference или filenotfound, потому что вы можете проактивно проверить их. Только исключения, которые вы знаете, могут произойти, но вы ничего не можете сделать. Помимо этого, ради вашего состояния данных, пусть он сбой.

Если вы глотаете исключения, обычно это означает, что вы не понимаете свою программу или почему вы получаете исключение. Catching System.Exception является родителем плаката кода запахов...

Ответ 3

На самом деле, я очень редко использую блок catch, кроме ведения журнала. finally гораздо более распространен для меня. В большинстве случаев lock или using делают все, что я могу с пользой сделать (и действительно, это также finally).

У Эрика Липперта есть запись запись в блогах исключений, которая может быть полезна.

Ответ 4

Как правило, IMO лучше помещать меньшие куски, которые не поддаются контролю в попытке поймать. Если вы скажете:

try
{
   //anything that could possibly go wrong
   //This kind of thing is only good for Logging IMO and could be done in
   //Global.asax
}

Как вы могли бы знать, что делать в вашем методе catch, потому что это может быть что угодно...

Его гораздо лучше:

try
{
   //divide user imputs
}
catch(DivideByZeroException)
{
  // tell user bad inputs ect....
}
catch (Exception e)
{
    //If you choose to throw the exception you should
    //***********************
    throw; 
    //VS
    throw ex; //Throw ex will restart the stack trace  
    // recover
}
finally
{
    //Clean up resources and continue
}

В котором, наконец, всегда выполняется

Ответ 5

Ключом к этому вопросу является следующая строка:

// recover

Чтобы восстановить, вы должны знать, что и как восстановить. И это предполагает, что можно восстановить, чего довольно часто не бывает.

Вы должны использовать только catch часть try/catch/finally, чтобы проглатывать исключение, когда знаете, как обрабатывать исключение, когда знаете, как его восстановить, и когда вы уверены, что можете сделать это, не покидая приложение в несогласованном или недействительном состоянии.

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

Ответ 6

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

Ответ 7

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

Для веб-приложений там Global.asax, для консольной программы, просто оберните ваш Main() в try/catch, для служб, там AppDomain.CurrentDomain.UnhandledException и т.д.

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

Ответ 8

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

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

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

Ответ 9

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

Кроме того, чтобы защитить от неперехваченных исключений, мы присоединяем UnhandledExceptionEventHandler к AppDomain.CurrentDomain.

Ответ 10

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

Вы должны быть осторожны, ловить общие исключения никогда не бывает хорошей идеей. Вы должны решить, какой слой вы хотите обработать.

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

Таким образом, вы можете иметь дело с каждым исключением в каждом отдельном случае. Общее исключение, о котором вы не будете знать, что делать.

Ответ 11

public void functionName  
{
  try
  {
     //your codes
     //sometimes 'return' shows exceptions
  }
  catch(Exception e)
  {
    messagebox.show(e.Tostring());   //to know what is the exception
  }
  finally
  {
  }
}

Ответ 12

попробуйте поймать С#:

try{

}
catch (NullReferenceException en)
{

}