Вызов Console.WriteLine(ex.Message) для предотвращения предупреждающего сообщения

Обычно мы ловим исключение на верхнем уровне кода, например, в графическом интерфейсе (формы).

Но у меня обычно такой код

try
{
}
catch(Exception ex)
{
  Console.WriteLine(ex.Message);
  MessageBox.Show("Application has encountered error....");
}

Я мог бы просто поймать (Exception) без идентификатора, потому что мне не нужно сообщение во время выполнения, но для отладочной сборки, безусловно, удобно прерываться на операторе catch. Поэтому я обычно пишу Console.WriteLine, чтобы предотвратить много предупреждений о неиспользуемой переменной ex. У меня много случаев Console.WriteLine(ex.Message) в моем коде. Уменьшается ли эта производительность по затратам?

Примечание. Заголовок изменен с «Имеет ли Console.WriteLine(ex.Message) стоимость производительности?» на «Вызов Console.WriteLine(ex.Message) для предотвращения предупреждающего сообщения»


person Nap    schedule 29.06.2009    source источник


Ответы (6)


Это множественный вопрос в 1, поэтому я попытаюсь развернуть его:

Во-первых

try{
  ...
}
catch(Exception) 
{
}

Совершенно допустимый синтаксис. Добавление Console.WriteLine(ex.Message) только для того, чтобы компилировать без предупреждения, не следует делать.

Во-вторых

Console.WriteLine — неподходящий способ диагностики, посмотрите на Trace.WriteLine или, что еще лучше, на фреймворк ведения журналов. Конечно, Console.Writeline имеет свою стоимость, стоимость не слишком серьезная, тем не менее звонок сделан, и он имеет свою стоимость.

В-третьих

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

person Sam Saffron    schedule 29.06.2009

Вы можете создать метод расширения, который будет отфильтрован в режиме отладки.

public static Exception
{

    [Conditional("DEBUG")]
    public static void Dump( this Exception ex )
    {
        Console.WriteLine( ex.ToString() );
    }
}

Или даже лучше...

public static Exception
{
    public static void Log( this Exception ex )
    {
#if DEBUG
        Console.WriteLine( ex.ToString() );
#endif
        Logger.WriteLine( ex.ToString() );
    }
}

Затем в вашем коде замените Console.WriteLine( ex.ToString() ) на ex.Log();

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

person Paul Alexander    schedule 29.06.2009
comment
Ооо, очень мило - я не знал об этом. +1. - person Kenny Mann; 29.06.2009

Лучшим выбором может быть System.Diagnostics.Debug.WriteLine(ex) или System.Diagnostics.Trace.WriteLine(ex). Debug делает что-то, только если определен символ DEBUG, а Trace делает что-то, только если TRACE определен. По умолчанию ваша сборка выпуска не будет включать символ DEBUG.

person Brian Reiter    schedule 29.06.2009

Все имеет цену производительности. Вопрос в том, являются ли затраты на производительность значительными.

В этом случае я думаю, что лучше задать вопрос о том, куда идет вывод в приложении winforms, и почему вы отображаете только ex.Message, а не ex.ToString(). Зачем выбрасывать информацию?

person John Saunders    schedule 29.06.2009
comment
MessageBox.Show( ex.ToString() ) — плохой способ сообщить пользователю о возникновении ошибки. Сообщение часто занимает больше информации, чем полный экран, и скрывает любую кнопку OK. Исключение должно быть зарегистрировано, но не должно быть действительно показано пользователю. - person Paul Alexander; 29.06.2009
comment
Верно, но никто не предложил MessageBox.Show( ex.ToString() ). - person Fantius; 29.06.2009
comment
Я думаю, вы пропустили Console.WriteLine, чтобы предотвратить много предупреждений о неиспользуемой переменной ex. ... согласен с вами, это не тот вопрос, который нужно задавать. - person Sam Saffron; 29.06.2009
comment
Кстати, я думаю, что неправильно понял название вопроса, изменю его. Кроме того, я уже не планирую получать журнал, потому что у меня уже есть механизм ведения журнала на стороне хоста веб-службы, поэтому ведение журнала в клиенте было бы избыточным. Хотя может проще найти. Кроме того, я действительно намерен просто показать общее строковое сообщение о том, что доступ к веб-службе недоступен. - person Nap; 29.06.2009
comment
Регистрация на клиенте не является избыточной, поскольку исключение может не возникать на сервере. Например, это может быть проблема с сетью на стороне клиента. Кроме того, перестаньте думать, что исключение при вызове службы означает, что служба недоступна. Служба может просто возвращать ошибку SOAP. Это будет означать, что он доступен, но что-то не так с вашим только что сделанным вызовом. - person John Saunders; 29.06.2009

Чтобы избежать предупреждения: «Переменная 'ex' объявлена, но никогда не используется» в операторе catch, а также чтобы увидеть информацию, связанную с исключением, сделайте следующее:

try
{
    ...
}
catch(Exception)    // avoid warning
{
   // set break point inside exception
}

Установите точку останова внутри исключения и просмотрите переменную отладчика $exception либо в окне быстрого просмотра, либо в окне локальных переменных, либо в окне просмотра в Visual Studio (2008).

person Zamboni    schedule 05.01.2010
comment
+1 Я не знал о $exception. Это действительно полезно знать. - person Brian; 28.01.2010

В C# есть стоимость, которая не является незначительной при перехвате исключения. Проверьте сами, напишите что-то вроде этого:

  • Создать список строк
  • В этом списке сделайте 25% цифрами, а остальные — одной буквой.
  • Запустите цикл for, проходящий по каждому списку и выполняющий int foo = (int)myList[0], но оберните его в try/catch.

Поднимите ставку до 50%, затем до 75%, затем до 100%. 100% будет немного медленнее, но ненамного.

В этом конкретном примере реальным ответом будет использование вместо этого Int32.TryParse, но это показывает вам штраф.

person Kenny Mann    schedule 29.06.2009