Лучшая практика для обработки исключений в приложении Windows Forms?

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

117
задан Otiel 13 October 2011 в 13:56
поделиться

14 ответов

Еще несколько битов...

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

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

Никогда не "глотают" исключение, кроме наиболее хорошо зарегистрированных случаев, когда Вы абсолютно, положительно уверены, что выданное исключение приемлемо. Это никогда не будет почти иметь место. (И если это, удостоверьтесь, что Вы глотаете только конкретный , класс исключений - не делает никогда ласточка System.Exception.)

При создании библиотек (используемый приложением), не глотайте исключения, и не бойтесь позволить пузырю исключений. Не повторно бросайте, если у Вас нет чего-то полезного для добавления. Не делайте никогда (в C#), делают это:

throw ex;

, Поскольку Вы сотрете стек вызовов. Если необходимо повторно бросить (который иногда необходим, такой как тогда, когда с помощью Блока Обработки исключений Библиотеки Предприятия), используйте следующее:

throw;

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

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

79
ответ дан John Rudy 24 November 2019 в 02:08
поделиться

Я глубоко согласовываю правило:

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

причина состоит в том что:

  • при первой записи кода, скорее всего, у Вас не будет полного знания кода с 3 сторонами.NET FCL lirary или Ваши коллеги последние вклады. В действительности Вы не можете отказаться писать код, пока Вы не знаете каждой возможности исключения хорошо. Так
  • я constanly находят, что я использую попытку/выгоду (Исключение исключая) просто, потому что я хочу к защищенному сам от неизвестных вещей, и, как Вы заметили, я ловлю Исключение, не более определенное такое как OutOfMemoryException и т.д. И, я всегда делаю исключение открываемым мне (или QA) ForceAssert. AlwaysAssert (ложь, напр. ToString ());

ForceAssert. AlwaysAssert является моим персональным способом Трассировки. Утверждайте только независимо от того, определяется ли макрос ОТЛАДКИ/ТРАССИРОВКИ.

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

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

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

Для кода WinForms, золотое правило, которое я всегда соблюдаю:

  • Всегда попытка/выгода (Исключение) Ваш код обработчика событий

, это будет, защищал Ваш UI, являющийся всегда применимым.

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

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

1
ответ дан zhaorufei 24 November 2019 в 02:08
поделиться

n мой опыт я счел целесообразным ловить исключения, когда я знаю, что собираюсь быть созданием их. Для экземпляров, когда я нахожусь в веб-приложении и я делаю Ответ. Перенаправление, я знаю, что буду получать Систему. ThreadAbortException. Так как это является намеренным, я просто имею выгоду для определенного типа и просто глотаю его.

try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}
1
ответ дан Jeff Keslinke 24 November 2019 в 02:08
поделиться

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

Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}

выполнение этого заставит отслеживание стека заканчиваться в операторе выгоды. (избегайте этого)

catch(Exception e)
// logging
throw e;
}
1
ответ дан Brad8118 24 November 2019 в 02:08
поделиться

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

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

1
ответ дан BKimmel 24 November 2019 в 02:08
поделиться

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

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

пример:

void Main()
{
  try {
    DoStuff();
  }
  catch(Exception ex) {
    LogStuff(ex.ToString());
  }

void DoStuff() {
... Stuff ...
}

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

2
ответ дан Echostorm 24 November 2019 в 02:08
поделиться

, Когда я должен повторно бросить исключение?

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

я должен попытаться иметь центральный механизм обработки ошибок некоторого вида?

я пишу, что файл журнала... довольно легкий для приложения

WinForm, Делает обрабатывающие исключения, которые могли бы быть выданы, производительность совершила нападки по сравнению с упреждающим тестированием вещей как то, существует ли файл на диске?

я не уверен в этом, но я полагаю, что это - хорошая практика к thow исключениям... Я подразумеваю, что можно спросить, существует ли файл и если он не бросает FileNotFoundException

, Должен весь исполняемый код быть включенным в try-catch-finally блоки?

yeap

Является там какими-либо временами, когда пустой блок выгоды мог бы быть приемлемым?

Да, скажем, Вы хотите показать дату, но у Вас нет подсказки, как та дата была хранилищами (dd/mm/yyyy, mm/dd/yyyy, и т.д.) Вы пробуете tp, анализируют его, но если это перестало работать, просто продолжают идти..., если это не важно Вам... Я сказал бы да, существует

1
ответ дан sebagomez 24 November 2019 в 02:08
поделиться

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

  1. Явно проверка на все известные состояния ошибки*
  2. Добавляет попытку/выгоду вокруг кода, если Ваш не уверены, если Вы смогли обработать все случаи
  3. , Добавляет попытка/выгода вокруг кода, если интерфейс.NET, который Вы называете, выдает исключение
  4. , Добавляет попытка/выгода вокруг кода, если это пересекается, порог сложности для Вас
  5. Добавляют попытку/выгоду вокруг кода если для проверки работоспособности: Вы утверждаете, что ЭТОГО НИКОГДА не должно ПРОИСХОДИТЬ
  6. Как правило, я не использую исключения в качестве замены для кодов возврата. Это хорошо для.NET, но не меня. У меня действительно есть исключения (hehe) к этому правилу, хотя, оно зависит от архитектуры приложения Ваш, продолжают работать также.

причина *Within. Нет никакой потребности проверить, чтобы видеть, говорят ли, что космический луч поразил Ваши данные, вызывающие паре битов быть зеркально отраженным. Понимание, что "разумно", является полученным навыком для инженера. Трудно определить количество, все же легкий постигнуть интуитивно. Таким образом, я могу легко объяснить, почему я использую попытку/выгоду в каком-то конкретном экземпляре, все же мне трудно пропитывать другого с этим тем же знанием.

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

4
ответ дан pezi_pink_squirrel 24 November 2019 в 02:08
поделиться

Мне нравится философия не ловли чего-либо, что я не предназначаю на обработке, безотносительно обработки средств в моем конкретном контексте.

я ненавижу его, когда я вижу код, такой как:

try
{
   // some stuff is done here
}
catch
{
}

я время от времени видел это, и довольно трудно найти проблемы, когда кто-то 'ест' исключения. Коллега, которого я имел, делает это, и это имеет тенденцию заканчивать тем, что было участником непрекращающегося потока проблем.

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

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

4
ответ дан itsmatt 24 November 2019 в 02:08
поделиться

Вот несколько инструкций, за которыми я следую

  1. Сбой Быстро: Это - больше генерирующейся инструкции по исключению Для каждого предположения, что Вы делаете и каждый параметр, что Вы входите в функцию, делают проверку, чтобы удостовериться, что Вы начинаетесь с правильными данными и что предположения, которые Вы делаете, корректны. Типичные проверки включают, аргумент, не пустой, аргумент в ожидаемом диапазоне и т.д.

  2. При переброске отслеживания стека заповедника - Это просто переводит в использование броска, когда перебросок вместо выдает новое Исключение (). Кроме того, если Вы чувствуете, что можно добавить, что больше информации тогда обертывает исходное исключение как внутреннее исключение. Но если Вы ловите исключение только для входа, оно тогда определенно использует бросок;

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

  4. Действительно сцепляют глобальные обработчики исключений и удостоверяются, что зарегистрировали как можно больше информации. Поскольку winforms сцепляют обоих appdomain и распараллеливают события необработанного исключения.

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

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

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

9
ответ дан Sijin 24 November 2019 в 02:08
поделиться

Весь совет, отправленный здесь до сих пор, хорош и стоит учесть.

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

наивное эмпирическое правило является "блоками попытки/выгоды, являются дорогими". Это не на самом деле верно. Попытка не является дорогой. Это - ловля, где система должна создать Объект исключения и загрузить его отслеживанием стека, это дорого. Существует много случаев, в которых исключение является, ну, в общем, достаточно исключительным, что оно прекрасно подходит для обертывания кода в блок попытки/выгоды.

, Например, если Вы заполняете Словарь, это:

try
{
   dict.Add(key, value);
}
catch(KeyException)
{
}

часто быстрее, чем выполнение этого:

if (!dict.ContainsKey(key))
{
   dict.Add(key, value);
}

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

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

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

14
ответ дан Robert Rossney 24 November 2019 в 02:08
поделиться

Существует превосходный код статья CodeProject здесь . Вот несколько выделений:

  • План относительно худшего*
  • Проверка это рано
  • не доверяет внешним данным
  • , единственные надежные устройства: видео, мышь и клавиатура.
  • Записи могут перестать работать, также
  • , Код Безопасно
  • не выдает новое Исключение ()
  • , не помещают информацию о важном исключении о Поле сообщения
  • Помещенный единственная выгода (Исключение исключая) на поток
  • , Универсальные пойманные Исключения должны быть опубликованы
  • Исключение Журнала. ToString (); никогда не регистрируйте только Исключение. Обменивайтесь сообщениями!
  • не ловят (Исключение) несколько раз на поток
  • , никогда не глотают исключения
  • , код Очистки должен быть вставлен наконец в блоки
  • , Использование, "использующее" везде
  • , не возвращается, специальные значения на состояниях ошибки
  • не используют исключения, чтобы указать, что отсутствие ресурса
  • не использует обработку исключений в качестве средств возврата информации из метода
  • исключения Использования для ошибок, которые не должны быть проигнорированы
  • , не очищают отслеживание стека, когда перебросок исключения
  • Старается не изменять исключения, не добавляя семантическое значение
  • , Исключения должны быть отмечены [сериализуемые]
  • , Когда в сомнении, не Утверждайте, выдавайте Исключение
  • , Каждый класс исключений должен иметь, по крайней мере, трех исходных конструкторов
  • Быть осторожным при использовании AppDomain. Событие
  • UnhandledException не перестраивает колесо
  • , не используют Неструктурированную Обработку ошибок (VB.Net)
62
ответ дан Rubens Farias 24 November 2019 в 02:08
поделиться

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

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

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

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

4
ответ дан 24 November 2019 в 02:08
поделиться

Обратите внимание, что в Windows Forms есть собственный механизм обработки исключений. Если кнопка в форме нажата, и ее обработчик выдает исключение, которое не перехвачено в обработчике, Windows Forms отобразит свой собственный диалог необработанных исключений.

Чтобы не отображать диалог необработанных исключений, и перехватывать такие исключения для ведения журнала и / или для предоставления собственного диалога об ошибках, который вы можете прикрепить к событию Application.ThreadException перед вызовом Application.Run () в вашем методе Main ().

15
ответ дан 24 November 2019 в 02:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: