Меню

Обработка ошибок windows forms

A few more bits …

You absolutely should have a centralized exception handling policy in place. This can be as simple as wrapping Main() in a try/catch, failing fast with a graceful error message to the user. This is the «last resort» exception handler.

Preemptive checks are always correct if feasible, but not always perfect. For example, between the code where you check for a file’s existence and the next line where you open it, the file could have been deleted or some other issue may impede your access. You still need try/catch/finally in that world. Use both the preemptive check and the try/catch/finally as appropriate.

Never «swallow» an exception, except in the most well-documented cases when you are absolutely, positively sure that the exception being thrown is livable. This will almost never be the case. (And if it is, make sure you’re swallowing only the specific exception class — don’t ever swallow System.Exception.)

When building libraries (used by your app), do not swallow exceptions, and do not be afraid to let the exceptions bubble up. Do not re-throw unless you have something useful to add. Do not ever (in C#) do this:

throw ex;

As you will erase the call stack. If you must re-throw (which is occasionally necessary, such as when using the Exception Handling Block of Enterprise Library), use the following:

throw;

At the end of the day, the very vast majority of exceptions thrown by a running application should be exposed somewhere. They should not be exposed to end users (as they often contain proprietary or otherwise valuable data), but rather usually logged, with administrators notified of the exception. The user can be presented with a generic dialog box, maybe with a reference number, to keep things simple.

Exception handling in .NET is more art than science. Everyone will have their favorites to share here. These are just a few of the tips I’ve picked up using .NET since day 1, techniques which have saved my bacon on more than one occasion. Your mileage may vary.

Обработка исключений в приложении, способы сбра информации об исключениях, настройка провайдера для отчета об ошибках, обработка неотловленных исключений, настройка лога сообщений

Flexberry Platform в сборке ICSSoft.STORMNET.UI.dll содержит классы для обработки исключительных ситуаций.

Простое отображение ошибки

Стандартный сценарий отображения Exception в специальной форме выглядит так:

try
{
  throw new Exception("Опаньки!");
  //...
}
catch(Exception ex)
{
  ErrorBox.Show(ex);
}

Способы сбора информации об исключениях

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

Итак, чтобы получить снимки экрана:

//Сделаем снимок только формы
Bitmap screen1 = ErrorBox.CaptureScreenShot(formToCapture);
//или снимем весь экран
Bitmap screen2 = ErrorBox.CaptureScreenShot();

Для того чтобы вывести эти снимки и сообщение:

//...
catch(Exception ex)
{
  List<Bitmap> screens = new List<Bitmap>();
  screens.Add(screen1);
  screens.Add(screen2);
  ErrorBox.Show(ex, screens, "Дополнительная информация об ошибке: переменная Х имеет значение:" + X);
}

Провайдеры отчётов об ошибках

Пользователь имеет возможность выгрузить информацию об ошибке, нажав на соответствующую кнопку на форме ошибки. По-умолчанию доступны 3 провайдера отчётов об ошибках:

  • Сохранить отчёт об ошибке на диск
  • Отправить отчет по электронной почте
  • Скопировать информацию в буфер обмена

Первые 2 варианта поддерживают сохранение изображений экрана (вся информация помещается в один zip-файл). В буфер обмена попадает только текстовая информация.

Чтобы добавить свой провайдер отчёта об ошибке, нужно унаследоваться от интерфейса IBugReportProvider и в конфигурационном файле добавить настройку BugReportProviders, в которой указать полные имена типов провайдеров, разделённые вертикальной чертой.

Важно: нельзя подключить 2 провайдера с одинаковым MenuItemName (будет подключен только первый из них).

Для работы с данными ошибки можно использовать статические методы класса ErrorBox.

Отправка сообщения об ошибке по электронной почте

В стандартном окне сообщения об ошибке существует возможность отправить письмо с сообщением об ошибке.

Форма исключения

При выборе пункта меню “Отправить по электронной почте…” запускается почтовый клиент по умолчанию. Письмо содержит вложение с архивом, в котором находятся снимок экрана, описание ошибки и информация о текущей системной конфигурации.
Сообщение

Для запуска почтового клиента используется интерфейс MAPI. Адрес отправки, заголовок и текст сообщения могут быть настроены в конфигурационном файле приложения с помощью ключей BugReportEmailAddress, BugReportEmailTitle, BugReportEmailBody.

Пример:

<add key="BugReportEmailAddress" value="user@perm.ru" />
<add key="BugReportEmailTitle" value="Ошибка в Кошках или Лапах" />
<add key="BugReportEmailBody" value="Текст сообщения" />

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

Адрес: пробел (пустую строку MAPI не принимает).

Тема: Ошибка {ИмяИсполнимогоФайла}.

Текст сообщения: В процессе работы пользователя {ИмяWindowsПользователя} в программе { ИмяИсполнимогоФайла} произошла ошибка. Дополнительная информация находится во вложении.

Замечание:

Для временного хранения архива используется папка Environment.SpecialFolder.InternetCache. Однако файл автоматически не удаляется, т.к. он не может быть удален до отправки сообщения.

Добавление информации о прикладной системе

Класс ICSSoft.STORMNET.Windows.Forms.ErrorBox содержит статический делегат, который позволяет собрать информацию о системе для того, чтобы она попала в информацию об ошибке.

/// <summary>
/// Делегат для сбора информации о прикладной системе
/// </summary>
/// <returns></returns>
public delegate string GetCurrentAppInfoDelegate();

/// <summary>
/// Делегат, который должен собрать информацию о прикладном приложении. Его результат будет присобачен к общей информации о системе.
/// </summary>
public static GetCurrentAppInfoDelegate GetCurrentAppInfo = null;

Обработка неотловленных исключений в прикладных системах

Чтобы пользователям не показывалась “страшная” форма с информацией об ошибке, если случилось неотловленное исключение, нужно подписаться на события Application.ThreadException и System.AppDomain.CurrentDomain.UnhandledException для того чтобы обработать их правильным образом.

Генератор приложений Flexberry добавляет строки

System.Windows.Forms.Application.ThreadException += ICSSoft.STORMNET.Windows.Forms.ErrorBox.ApplicationThreadException;
System.AppDomain.CurrentDomain.UnhandledException += ICSSoft.STORMNET.Windows.Forms.ErrorBox.CurrentDomainUnhandledException;

в метод Main приложения (в скобках программиста). Обработчики ICSSoft.STORMNET.Windows.Forms.ErrorBox.ApplicationThreadException и ICSSoft.STORMNET.Windows.Forms.ErrorBox.CurrentDomainUnhandledException просто запускают стандартную ErrorForm с информацией об исключении. Если требуется особая логика, то можно использовать собственный обработчик события.

Подключение лога ошибок

Чтобы включить лог ошибок достаточно указать такой атрибут в файле конфигурации:

<add key="ErrorLog" value="true" />

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

Содержание

  1. Обработка исключений
  2. Конструкция try..catch..finally
  3. Обработка исключений и условные конструкции
  4. Обработка исключений в winforms-приложениях
  5. Простое отображение ошибки
  6. Способы сбора информации об исключениях
  7. Провайдеры отчётов об ошибках
  8. Отправка сообщения об ошибке по электронной почте
  9. Добавление информации о прикладной системе
  10. Обработка неотловленных исключений в прикладных системах
  11. Подключение лога ошибок
  12. обработка исключений
  13. Лучшие методики обработки исключений
  14. Использование блоков try/catch/finally для восстановления после ошибок или высвобождения ресурсов
  15. Обработка общих условий без выдачи исключений
  16. Устранение исключений при разработке классов
  17. Выдача исключений вместо возврата кода ошибки
  18. Завершайте имена классов исключений словом Exception
  19. Включение трех конструкторов в пользовательские классы исключений
  20. Обеспечение доступности данных об исключении при удаленном выполнении кода
  21. Использование грамматически правильных сообщений об ошибке
  22. Включение локализованной строки сообщения в каждое исключение
  23. Предоставление дополнительных свойств в пользовательских исключениях по мере необходимости
  24. Размещение операторов throw для удобной трассировки стека
  25. Использование методов построителя исключений
  26. Восстановление состояния, если методы не выполняются из-за исключения
  27. Обработка необработанных исключений (C#)
  28. Введение
  29. Исполнение кода при Error возникновении события
  30. Получение сведений о необработанном исключении
  31. Уведомление разработчика при возникновении необработанного исключения
  32. Что насчет использования пользовательской страницы ошибок
  33. Сводка
  34. Дополнительные материалы

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

Конструкция try..catch..finally

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

Рассмотрим следующий пример:

В данном случае происходит деление числа на 0, что приведет к генерации исключения. И при запуске приложения в режиме отладки мы увидим в Visual Studio окошко, которое информирует об исключении:

2.10

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

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

выполнение программы остановится. CLR найдет блок catch и передаст управление этому блоку.

После блока catch будет выполняться блок finally.

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

И, наоборот, при наличии блока finally мы можем опустить блок catch и не обрабатывать исключение:

Однако, хотя с точки зрения синтаксиса C# такая конструкция вполне корректна, тем не менее, поскольку CLR не сможет найти нужный блок catch, то исключение не будет обработано, и программа аварийно завершится.

Обработка исключений и условные конструкции

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

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

Источник

Обработка исключений в winforms-приложениях

Flexberry Platform в сборке ICSSoft.STORMNET.UI.dll содержит классы для обработки исключительных ситуаций.

Простое отображение ошибки

Стандартный сценарий отображения Exception в специальной форме выглядит так:

Способы сбора информации об исключениях

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

Итак, чтобы получить снимки экрана:

Для того чтобы вывести эти снимки и сообщение:

Провайдеры отчётов об ошибках

Пользователь имеет возможность выгрузить информацию об ошибке, нажав на соответствующую кнопку на форме ошибки. По-умолчанию доступны 3 провайдера отчётов об ошибках:

Первые 2 варианта поддерживают сохранение изображений экрана (вся информация помещается в один zip-файл). В буфер обмена попадает только текстовая информация.

Важно: нельзя подключить 2 провайдера с одинаковым MenuItemName (будет подключен только первый из них).

Отправка сообщения об ошибке по электронной почте

В стандартном окне сообщения об ошибке существует возможность отправить письмо с сообщением об ошибке.

error form

При выборе пункта меню “Отправить по электронной почте…” запускается почтовый клиент по умолчанию. Письмо содержит вложение с архивом, в котором находятся снимок экрана, описание ошибки и информация о текущей системной конфигурации. letter

Пример:

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

Адрес: пробел (пустую строку MAPI не принимает).

Текст сообщения: В процессе работы пользователя <ИмяWindowsПользователя>в программе < ИмяИсполнимогоФайла>произошла ошибка. Дополнительная информация находится во вложении.

Замечание:

Добавление информации о прикладной системе

Класс ICSSoft.STORMNET.Windows.Forms.ErrorBox содержит статический делегат, который позволяет собрать информацию о системе для того, чтобы она попала в информацию об ошибке.

Обработка неотловленных исключений в прикладных системах

Чтобы пользователям не показывалась “страшная” форма с информацией об ошибке, если случилось неотловленное исключение, нужно подписаться на события Application.ThreadException и System.AppDomain.CurrentDomain.UnhandledException для того чтобы обработать их правильным образом.

Генератор приложений Flexberry добавляет строки

в метод Main приложения (в скобках программиста). Обработчики ICSSoft.STORMNET.Windows.Forms.ErrorBox.ApplicationThreadException и ICSSoft.STORMNET.Windows.Forms.ErrorBox.CurrentDomainUnhandledException просто запускают стандартную ErrorForm с информацией об исключении. Если требуется особая логика, то можно использовать собственный обработчик события.

Подключение лога ошибок

Чтобы включить лог ошибок достаточно указать такой атрибут в файле конфигурации:

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

Источник

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

Разработать приложение Windows Forms, реализующее обработку различных исключений Format Exception, Index out of Range и извещающую пользователя об обработке соответствующих исключений:
1) деление на ноль
2) исключение формата
3) иск. выхода пар-ра за границы
Это я сделала, а вот какую еще можно взять функцию, которая обрабатывала еще одно исключение?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
<
public partial class Form1 : Form
<
public Form1()
<
InitializeComponent();
>

private void button1_Click(object sender, EventArgs e)
<
double a = 0;
double b = 0;
try
<
a = Convert.ToDouble(textBox1.Text);
b = Convert.ToDouble(textBox2.Text);
>
catch (System.Exception ex)
<
MessageBox.Show(«Ошибка формата!»);
>
label2.Text = Convert.ToString(a + b);
>

private void button2_Click(object sender, EventArgs e)
<
string[] s1 = new string[2] < «Иванов И.И.», «Петрова В.А»>;
try
<
int i = Convert.ToInt16(textBox3.Text)-1;
label3.Text = s1[i];
>
catch (System.Exception ex1)
<
label3.Text = «Ошибка, неверные данные!»;
>

private void button3_Click(object sender, EventArgs e)
<
int a, b, result = 0;

a = Convert.ToInt16(textBox4.Text);
b = Convert.ToInt16(textBox5.Text);

result = a / b;
label6.Text = result.ToString();
>
catch (System.Exception ex2)
<
label6.Text = «Ошибка. Неверные данные или деление на 0»;
>

private void Form1_Load(object sender, EventArgs e)
<

Источник

Лучшие методики обработки исключений

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

Использование блоков try/catch/finally для восстановления после ошибок или высвобождения ресурсов

Обработка общих условий без выдачи исключений

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

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

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

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

Устранение исключений при разработке классов

Класс может предоставлять методы и свойства, позволяющие избежать вызова, способного выдать исключение. Например, класс FileStream содержит методы, позволяющие определить, достигнут ли конец файла. Это позволяет избежать появления исключения, создаваемого в случае выполнения чтения после окончания файла. В следующем примере показан способ чтения до конца файла без выдачи исключения.

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

Выдача исключений вместо возврата кода ошибки

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

Создавайте новый класс исключений, только если предопределенное исключение не подходит. Пример:

Вызывайте исключение InvalidOperationException, если значение свойства или вызов метода не соответствуют текущему состоянию объекта.

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

Завершайте имена классов исключений словом Exception

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

Включение трех конструкторов в пользовательские классы исключений

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

Exception(), использующий значения по умолчанию.

Exception(String), принимающий строковое сообщение.

Exception(String, Exception), принимающий строковое сообщение и внутреннее исключение.

Обеспечение доступности данных об исключении при удаленном выполнении кода

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

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

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

Использование грамматически правильных сообщений об ошибке

Составляйте понятные предложения, указывая в конце знаки препинания. Каждое предложение в строке, назначенной свойству Exception.Message, должно заканчиваться точкой. Например, «Таблица журнала переполнена.» будет подходящей строкой сообщения.

Включение локализованной строки сообщения в каждое исключение

Сообщение об ошибке, показываемое пользователю, извлекается из свойства Exception.Message созданного исключения, а не из имени класса исключения. Как правило, вы присваиваете значение свойству Exception.Message, передав строку сообщения аргументу message конструктора исключений.

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

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

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

Размещение операторов throw для удобной трассировки стека

Использование методов построителя исключений

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

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

Восстановление состояния, если методы не выполняются из-за исключения

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

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

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

В этом примере показано использование throw для повторного порождения исходного исключения. Это позволяет вызывающим объектам проще установить фактическую причину проблемы, не обращаясь к свойству InnerException. Альтернативным способом является выдача нового исключения с включением исходного исключения в качестве внутреннего:

Источник

Обработка необработанных исключений (C#)

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

Введение

При возникновении необработанного исключения в приложении ASP.NET оно передается в среду выполнения ASP.NET, которая вызывает Error событие и отображает соответствующую страницу ошибки. Существует три разных типа страниц ошибок: желтый экран «ошибка времени выполнения» (ИСОД); Сведения об исключении ИСОД; и пользовательские страницы ошибок. В предыдущем учебном курсе мы настроили приложение на использование настраиваемой страницы ошибок для удаленных пользователей и сведений об исключении, исод для пользователей, посещенных локально.

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

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

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

Исполнение кода при Error возникновении события

События предоставляют объекту механизм для сигнализации о том, что произошло нечто интересное, а другой объект — для выполнения кода в ответе. Как разработчик ASP.NET вы привыкли думать о событиях. Если вы хотите выполнить некоторый код, когда посетитель щелкнет определенную кнопку, создайте обработчик событий для этого Click события кнопки и вставьте в него код. Учитывая, что среда выполнения ASP.NET создает свое Error событие всякий раз, когда возникает необработанное исключение, оно следует за тем, чтобы код для записи сведений об ошибке перейдет в обработчик событий. Но как создать обработчик событий для Error события?

image2

При развертывании приложения ASP.NET необходимо скопировать Global.asax файл в рабочую среду. Global.asax.cs Файл, созданный в WAP, не нужно копировать в рабочую среду, так как этот код компилируется в сборку проекта.

Аналогичным образом можно удалить все обработчики событий, созданные ненужным шаблоном глобального класса приложений. Для этого учебника требуется обработчик событий только для Error события. Удалите другие обработчики событий из Global.asax файла.

Получение сведений о необработанном исключении

На этом этапе у нас есть файл Global. asax с Application_Error обработчиком событий. При выполнении этого обработчика событий необходимо уведомить разработчика об ошибке и записать сведения о нем. Для выполнения этих задач сначала необходимо определить сведения о возникшем исключении. Используйте GetLastError метод объекта Server для получения сведений о необработанном исключении, которое привело Error к срабатыванию события.

На этом этапе у вас есть вся информация, необходимая для написания кода, который будет записывать сведения об исключении в таблицу базы данных. Можно создать таблицу базы данных со столбцами для каждой из подробных сведений об ошибках — типа, сообщения, трассировки стека и т. д. Вместе с другими полезными сведениями, такими как URL-адрес запрашиваемой страницы и имя пользователя, выполнившего вход в систему. В Application_Error обработчике событий можно подключиться к базе данных и вставить в нее запись. Аналогичным образом можно добавить код для оповещения разработчика об ошибке по электронной почте.

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

Уведомление разработчика при возникновении необработанного исключения

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

Элемент содержит параметры SMTP-сервера, используемые SmtpClient классом при отправке сообщения электронной почты. У компании, в которой размещен веб-узел, вероятно, есть SMTP-сервер, который можно использовать для отправки электронной почты из приложения. Дополнительные сведения о параметрах SMTP-сервера, которые следует использовать в приложении, см. в разделе о поддержке веб-узла.

Добавьте следующий код в Application_Error обработчик событий, чтобы отправить разработчику сообщение электронной почты при возникновении ошибки:

image5

Рис. 2. разработчик отправил уведомление по электронной почте при наличии необработанного исключения
(Щелкните, чтобы просмотреть изображение с полным размером)

image8

Рис. 3. уведомление по электронной почте содержит сведения об исключении Исод в виде вложения
(Щелкните, чтобы просмотреть изображение с полным размером)

Что насчет использования пользовательской страницы ошибок

В этом учебнике было показано, как использовать Global.asax и Application_Error обработчик событий для выполнения кода при возникновении необработанного исключения. В частности, мы использовали этот обработчик событий для уведомления разработчика об ошибке; Мы можем расширить его, чтобы также регистрировать сведения об ошибке в базе данных. Наличие Application_Error обработчика событий не влияет на работу конечного пользователя. Они по-прежнему видят настроенную страницу ошибки, сведения об ошибке ИСОД, ошибку времени выполнения ИСОД или настраиваемую страницу ошибки.

image11

Рис. 4. при возникновении ошибки браузер перенаправляется на URL-адрес настраиваемой страницы ошибок
(Щелкните, чтобы просмотреть изображение с полным размером)

Побочным результатом является то, что запрос, в котором произошло необработанное исключение, заканчивается, когда сервер отвечает на перенаправление HTTP 302. Последующий запрос к пользовательской странице ошибок — это новый запрос. к этому моменту модуль ASP.NET отменил сведения об ошибке и, более того, не имеет способа связать необработанное исключение в предыдущем запросе с новым запросом для настраиваемой страницы ошибки. Именно поэтому функция GetLastError возвращает null при вызове со страницы настраиваемой ошибки.

Тем не менее, пользовательская страница ошибок может быть выполнена во время того же запроса, что привело к ошибке. Server.Transfer(url) Метод передает выполнение на указанный URL-адрес и обрабатывает его в рамках одного запроса. Код в Application_Error обработчике событий можно переместить в класс кода программной части пользовательской страницы ошибки, заменив его в Global.asax следующим кодом:

Теперь при возникновении необработанного исключения Application_Error обработчик событий передает управление соответствующей пользовательской странице ошибок на основе кода состояния HTTP. Так как управление было передано, пользовательская страница ошибки имеет доступ к необработанным сведениям об исключении через Server.GetLastError и может уведомлять разработчика об ошибке и записывать сведения о ней. Server.Transfer Вызов останавливает выполнение обработчика ASP.NET, перенаправляющего пользователя на настраиваемую страницу ошибки. Вместо этого содержимое страницы пользовательской ошибки возвращается в качестве ответа на страницу, вызвавшую ошибку.

Сводка

При возникновении необработанного исключения в веб-приложении ASP.NET среда выполнения ASP.NET создает Error событие и отображает настроенную страницу ошибки. Мы можем уведомить разработчика об ошибке, записать сведения о ней или обработать ее другим способом, создав обработчик событий для события ошибки. Существует два способа создания обработчика событий для HttpApplication таких событий, как Error : в Global.asax файле или в модуле HTTP. В этом учебнике было показано, как создать Error обработчик событий в Global.asax файле, который уведомляет разработчиков об ошибке с помощью сообщения электронной почты.

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

Поздравляем с программированием!

Дополнительные материалы

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

Источник

In order for it to bubble up into the scope of the calling UI, you would need to throw the exception once caught, or better yet, don’t throw it at all — since dividing by zero will cause the CLR to throw the exception if necessary. You could do simple checks here, while the Calc API call could still throw an exception.

For example, just check the data prior to the Calc call:

if (a > 0 && b > 0)
{
    var result = Calc(a, b);
}
else 
{
    //tell the user to input valid data
}

In the Calc method you could do a similar check and throw a relevant exception:

public int Calc(int a, int b)
{
    if (a <= 0) throw new ArgumentException("appropriate message here");
    if (b <= 0) throw new ArgumentException("appropriate message here");
    ...
}

the idea here is prevention of dividing by zero, but it might be a little excessive in your case, as the earlier example shows you can essentially provide the same behaviour, however now you need to catch the exception:

try
{
    var result = Calc(a, b);
}
catch //use appropriate exception catches
{
     //tell the user to input valid data
}

In order for it to bubble up into the scope of the calling UI, you would need to throw the exception once caught, or better yet, don’t throw it at all — since dividing by zero will cause the CLR to throw the exception if necessary. You could do simple checks here, while the Calc API call could still throw an exception.

For example, just check the data prior to the Calc call:

if (a > 0 && b > 0)
{
    var result = Calc(a, b);
}
else 
{
    //tell the user to input valid data
}

In the Calc method you could do a similar check and throw a relevant exception:

public int Calc(int a, int b)
{
    if (a <= 0) throw new ArgumentException("appropriate message here");
    if (b <= 0) throw new ArgumentException("appropriate message here");
    ...
}

the idea here is prevention of dividing by zero, but it might be a little excessive in your case, as the earlier example shows you can essentially provide the same behaviour, however now you need to catch the exception:

try
{
    var result = Calc(a, b);
}
catch //use appropriate exception catches
{
     //tell the user to input valid data
}

Разработать приложение Windows Forms, реализующее обработку различных исключений Format Exception, Index out of Range и извещающую пользователя об обработке соответствующих исключений:
1) деление на ноль
2) исключение формата
3) иск. выхода пар-ра за границы
Это я сделала, а вот какую еще можно взять функцию, которая обрабатывала еще одно исключение?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
double a = 0;
double b = 0;
try
{
a = Convert.ToDouble(textBox1.Text);
b = Convert.ToDouble(textBox2.Text);
}
catch (System.Exception ex)
{
MessageBox.Show(«Ошибка формата!»);
}
label2.Text = Convert.ToString(a + b);
}

private void button2_Click(object sender, EventArgs e)
{
string[] s1 = new string[2] { «Иванов И.И.», «Петрова В.А»};
try
{
int i = Convert.ToInt16(textBox3.Text)-1;
label3.Text = s1[i];
}
catch (System.Exception ex1)
{
label3.Text = «Ошибка, неверные данные!»;
}

}

private void button3_Click(object sender, EventArgs e)
{
int a, b, result = 0;

try
{

a = Convert.ToInt16(textBox4.Text);
b = Convert.ToInt16(textBox5.Text);

result = a / b;
label6.Text = result.ToString();
}
catch (System.Exception ex2)
{
label6.Text = «Ошибка. Неверные данные или деление на 0»;
}

}

private void Form1_Load(object sender, EventArgs e)
{

}
}
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

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

Конструкция try..catch..finally

Последнее обновление: 30.12.2021

Иногда при выполнении программы возникают ошибки, которые трудно предусмотреть или предвидеть, а иногда и вовсе невозможно. Например, при передачи файла по сети может неожиданно оборваться сетевое подключение.
такие ситуации называются исключениями. Язык C# предоставляет разработчикам возможности для обработки таких ситуаций. Для этого
в C# предназначена конструкция try…catch…finally.

try
{
	
}
catch
{
	
}
finally
{
	
}

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

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

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

Рассмотрим следующий пример:

int x = 5;
int y = x / 0;
Console.WriteLine($"Результат: {y}");
Console.WriteLine("Конец программы");

В данном случае происходит деление числа на 0, что приведет к генерации исключения. И при запуске приложения в
режиме отладки мы увидим в Visual Studio окошко, которое информирует об исключении:

Исключения в C#

В этом окошке мы видим, что возникло исключение, которое представляет тип System.DivideByZeroException,
то есть попытка деления на ноль. С помощью пункта View Details можно посмотреть более детальную информацию об исключении.

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

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

try
{
	int x = 5;
	int y = x / 0;
	Console.WriteLine($"Результат: {y}");
}
catch
{
	Console.WriteLine("Возникло исключение!");
}
finally
{
	Console.WriteLine("Блок finally");
}
Console.WriteLine("Конец программы");

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

int y = x / 0;

выполнение программы остановится. CLR найдет блок catch и передаст управление этому блоку.

После блока catch будет выполняться блок finally.

Возникло исключение!
Блок finally
Конец программы

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

Следует отметить, что в этой конструкции обязателен блок try. При наличии блока catch мы можем опустить блок finally:

try
{
	int x = 5;
	int y = x / 0;
	Console.WriteLine($"Результат: {y}");
}
catch
{
	Console.WriteLine("Возникло исключение!");
}

И, наоборот, при наличии блока finally мы можем опустить блок catch и не обрабатывать исключение:

try
{
	int x = 5;
	int y = x / 0;
	Console.WriteLine($"Результат: {y}");
}
finally
{
	Console.WriteLine("Блок finally");
}

Однако, хотя с точки зрения синтаксиса C# такая конструкция вполне корректна, тем не менее, поскольку CLR не сможет найти нужный блок
catch, то исключение не будет обработано, и программа аварийно завершится.

Обработка исключений и условные конструкции

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

Square("12"); // Квадрат числа 12: 144
Square("ab"); // !Исключение

void Square(string data)
{
    int x = int.Parse(data);
    Console.WriteLine($"Квадрат числа {x}: {x * x}");
}

Если пользователь передаст в метод не число, а строку, которая содежит нецифровые символы, то программа выпадет в ошибку. С одной стороны,
здесь как раз та ситуация, когда можно применить блок
try..catch, чтобы обработать возможную ошибку. Однако гораздо оптимальнее было бы проверить допустимость преобразования:

Square("12"); // Квадрат числа 12: 144
Square("ab"); // Некорректный ввод

void Square(string data)
{
    if (int.TryParse(data, out var x))
    {
        Console.WriteLine($"Квадрат числа {x}: {x * x}");
    }
    else
    {
        Console.WriteLine("Некорректный ввод");
    }
}

Метод int.TryParse() возвращает true, если преобразование можно осуществить, и false — если нельзя. При допустимости преобразования переменная x
будет содержать введенное число. Так, не используя try...catch можно обработать возможную исключительную ситуацию.

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

Содержание

  • Исключения (Exceptions) и инструкция try
  • Оговорка catch
  • Блок finally
  • Инструкция using
  • Выбрасывание исключений
  • Основные свойства System.Exception
  • Основные типы исключений
  • Директивы препроцессора
    • Pragma Warning
    • Атрибут Conditional
  • Классы Debug и Trace
    • TraceListener
    • Fail и Assert

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

Исключения (Exceptions) и инструкция try

Инструкция try отмечает блок кода как объект для обработки ошибок или очистки. После блока try обязательно должен идти либо блок catch, либо блок finally, либо они оба. Блок catch выполняется, когда внутри блока try возникает ошибка. Блок finally выполняется после того, как прекращает выполнять блок try (или, если присутствует, блок catch), независимо от того, выполнился ли он до конца или был прерван ошибкой, что позволяет выполнить так называемый код очистки.

Блок catch имеет доступ к объекту исключения (Exception), который содержит информацию об ошибке. Блок catch позволяет обработать исключительную ситуацию и как-либо скорректировать ошибку или выбросить новое исключение. Повторное выбрасывание исключения в блоке catch обычно применяется с целью логирования ошибок или чтобы выбросить новое, более специфическое исключение.

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

В целом конструкция try выглядит следующим образом:

try

{

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

}

catch (ExceptionA ex)

{

  ... // обработчик исключений типа ExceptionA

}

catch (ExceptionB ex)

{

  ... // обработчик исключений типа ExceptionB

}

finally

{

  ... // код очистки

}

Например, следующий код выбросит ошибку DivideByZeroException (поскольку делить на ноль нельзя) и наша программа завершить досрочно:

int x = 3, y = 0;

Console.WriteLine (x / y);

Чтобы этого избежать можно использовать конструкцию try:

try

{

  int x = 3, y = 0;

  Console.WriteLine (x / y);

}

catch (DivideByZeroException ex)

{

  Console.Write («y cannot be zero. «);

}

// выполнение программы продолжится отсюда

Обработка исключений довольно ресурсоёмкая операция, поэтому на практике для таких случаев как в примере ее лучше не использовать (лучше непосредственно перед делением проверить делить на равенство нулю).

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

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

Оговорка catch

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

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

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

Можно обработать несколько типов исключений с помощью нескольких оговорок catch:

try

{

  DoSomething();

}

catch (IndexOutOfRangeException ex) { ... }

catch (FormatException ex) { ... }

catch (OverflowException ex) { ... }

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

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

catch (StackOverflowException) // без переменной

{ ... }

Более того, в оговорке catch можно опустить и переменную и тип исключения — такая оговрка будет перехватывать все исключения:

Блок finally

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

Блок finally выполняется в следующих случаях:

  • после завершения блока catch
  • если выполнение блока try прервано jump-инструкциями: return, goto и т.д.
  • после выполнения блока try полностью, если исключений так и не было выброшено

Блок finally делает программу более прогнозируемой. Например, в следующем примере открываемый файл в итоге всегда будет закрыт, независимо от того, завершиться ли блок try без ошибок, или будет прерван выброшенным исключением, или сработает инструкция return если файл окажется пустым:

static void ReadFile()

{

  StreamReader reader = null;

  try

  {

      reader = File.OpenText («file.txt»);

      if (reader.EndOfStream) return;

      Console.WriteLine (reader.ReadToEnd());

  }

  finally

  {

      if (reader != null) reader.Dispose();

  }

}

В пример для закрытия файла вызывается метод Dispose. Использование этого метода внутри блока finally является стандартной практикой. C# даже позволяет заменить всю конструкцию инструкцией using.

Инструкция using

Многие классы инкапсулируют неуправляемые ресурсы, такие как дескриптор файла, соединение с базой данных и т.д. Эти классы реализуют интерфейс System.IDisposable, который содержит единственный метод без параметров Dispose, освобождающий соответствующие машинные ресурсы. Инструкция using предусматривает удобный синтаксис вызова метода Dispose для объектов реализующих IDisposable внутри блока finally:

using (StreamReader reader = File.OpenText («file.txt»))

{

  ...

}

Что эквивалентно следующей конструкции:

StreamReader reader = File.OpenText («file.txt»);

try

{

  ...

}

finally

{

  if (reader != null) ((IDisposable)reader).Dispose();

}

Выбрасывание исключений

Исключение может быть выброшено автоматически во время выполнения программы либо явно в коде программы с помощью ключевого слова throw:

static void Display (string name)

{

  if (name == null)

  throw new ArgumentNullException («name»);

  Console.WriteLine (name);

}

Также исключение может быть выброшено повторно внутри блока catch:

try { ... }

catch (Exception ex)

{

  // логирование ошибки

  ...

  throw; // повторное выбрасывание того же самого исключения

}

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

Если throw заменить на throw ex, то пример по прежнему будет работать, но свойство исключения StackTrace не будет отражать исходную ошибку.

Другой распространенный сценарий использования повторного выбрасывания исключения — повторное выбрасывание более специфического и конкретного типа исключения, чем было перехвачено ранее:

try

{

  ... // парсинг даты рождения из xml-данных

}

catch (FormatException ex)

{

  throw new XmlException («Неправильная дата рождения», ex);

}

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

Основные свойства System.Exception

К наиболее важным свойствам класса System.Exception можно отнести:

  • StackTrace — строка, представляющая все методы, которые были вызваны, начиная с того, в котором было выброшено исключение, и заканчивая тем, в котором содержится блок catch, перехвативший исключение;
  • Message — строка с описанием ошибки;
  • InnerException — содержит ссылку на объект Exeption, который вызвал текущее исключение (например, при повторном выбрасывании исключения).

Основные типы исключений

Следующие типы исключений являются наиболее распространенными в среде CLR и .NET Framework. Их можно выбрасывать непосредственно или использовать как базовые классы для пользовательских типов исключений.

  • System.ArgumentException — выбрасывается при вызове функции с неправильным аргументом.
  • System.ArgumentNullException — производный от ArgumentException класс, выбрасывается если один из аргументов функции неожиданно равен null.
  • System.ArgumentOutOfRangeException — производный от ArgumentException класс, выбрасывается когда аргумент функции имеет слишком большое или слишком маленькое значение для данного типа (обычно касается числовых типов). Например, такое исключение будет выброшено если попытаться передать отрицательное число в функцию, которая ожидает только положительные числа.
  • System.InvalidOperationException — выбрасывается когда состояние объекта является неподходящим для нормального выполнения метода, например, при попытке прочесть не открытый файл.
  • System.NotSupportedException — выбрасывается, когда запрошенный функционал не поддерживается, например, если попытаться вызвать метод Add для коллекции доступной только для чтения (свойство коллекции IsReadOnly возвращает true).
  • System.NotImplementedException — выбрасывается, когда запрошенный функционал еще не реализован.
  • System.ObjectDisposedException — выбрасывается при попытке вызвать метод объекта, который уже был уничтожен (disposed).

Директивы препроцессора

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

#define DEBUG

class MyClass

{

  int x;

  void Foo()

  {

      # if DEBUG

      Console.WriteLine («Testing: x = {0}», x);

      # endif

  }

}

В этом классе инструкции в методе Foo скомпилируются если определен символ DEBUG, а если его удалить — инструкции не скомпилируются. Символы препроцессора могут быть определены в исходном коде (как в примере), а могут быть переданы компилятору в командной строке с помощью параметра /define:symbol.

С директивами #if и #elif можно использовать операторы ||, && и ! с несколькими символами:

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

Директивы препроцессора схожи с условными конструкциями и статическими переменными, однако дают возможности, недоступные для последних:

  • условное включение атрибута
  • изменение типа, объявляемого для переменной
  • переключение между разными пространствами имен или псевдонимами типа в директиве using:

    using TestType =

      #if V2

          MyCompany.Widgets.GadgetV2;

      #else

          MyCompany.Widgets.Gadget;

      #endif

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

Полный список директив препроцессора:

  • #define symbol — определяет символ
  • #undef symbol — удаляет символ
  • #if symbol [оператор symbol2]... — условная компиляция; допустимые операторы ==, !=, && и ||
  • #else — выполняет код после #endif
  • #elif symbol [оператор symbol2] — объединяет #else и #if
  • #endif — конец условных директив
  • #warning text — текст предупреждения, которое появится в выдаче компилятора
  • #error text — текст ошибки, которая появится в выдаче компилятора
  • #line [число["файл"] | hidden]число указывает номер строки в исходном коде; файл — имя файла, которое появится в выдаче компилятора; hidden — дает указание дебагеру пропустить код от этой точки до следующей директивы #line
  • #region name — отмечает начало области
  • #endregion — отмечает конец области
  • #pragma warning

Pragma Warning

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

public class Foo

{

  static void Main() { }

  #pragma warning disable 414

  static string Message = «Hello»;

  #pragma warning restore 414

}

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

Если не указывать номер директива #pragma warning отменит или восстановит вывод всех предупреждений.

Если скомпилировать программу с параметром /warnaserror, то все не отмененные директивой #pragma warning предупреждения будут расцениваться компилятором как ошибки.

Атрибут Conditional

Атрибут Conditional указывает компилятору на необходимость игнорировать все обращения к определенному классу или методу, если заданный символ не был определен:

[Conditional («LOGGINGMODE»)]

static void LogStatus (string msg)

{

  ...

}

Это равносильно тому, что каждый вызов метода будет окружен условными директивами:

#if LOGGINGMODE

LogStatus («Message Headers: « + GetMsgHeaders());

#endif

Классы Debug и Trace

Статические классы Debug и Trace предлагают базовые возможности логирования. Оба класса схожи, отличие заключается в их назанчении. Класс Debug предназначен для отладочных сборок, класс Trace — для отладочных и финальных. В связи с этим все методы класса Debug определены с атрибутом [Conditional("DEBUG")], а методы класса Trace — с атрибутом [Conditional("TRACE")]. Это значит, что все обращения к Debug и Trace будут подавляться компилятором, пока не определен символ DEBUG или TRACE.

Класс Debug и Trace определяют методы Write, WriteLine и WriteIf. По умолчанию они отправляют сообщения в окно вывода отладчика:

Debug.Write («Data»);

Debug.WriteLine (23 * 34);

int x = 5, y = 3;

Debug.WriteIf (x > y, «x is greater than y»);

Класс Trace также содержит методы TraceInformation, TraceWarning и TraceError. Их действия зависят от зарегистрированных прослушивателей.

TraceListener

Классы Debug и Trace имеют свойство Listeners, которое представляет собой статическую коллекцию экземпляров TraceListener. Они отвечают за обработку данных, возвращаемых методами Write, Fail и Trace.

По умолчанию коллекция Listeners обоих классов включает единственный прослушиватель — DefaultTraceListener — стандартный прослушиватель, имеющий две ключевые возможности:

  • при подключении к отладчику (например, Visual Studio) сообщения записываются в окно вывода отладчика, во всех остальных случаях сообщения игнорируются
  • при вызове метода Fail отображается диалоговое окно, запрашивающее у пользователя дальнейшие действия: продолжить, прервать или повторить отладку (независимо от того, подключен ли отладчик)

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

Прослушиваетли трассировки можно написать с нуля (создав производный класс от TraceListener) или воспользоваться готовыми классами:

  • TextWriterTraceListener записывает в Stream или TextWriter или добавляет в файл; имеет четыре подкласса: ConsoleTraceListener, DelimitedListTraceListener, XmlWriterTraceListener и EventSchemaTraceListener
  • EventLogTraceListener записывает в журнал событий Windows
  • EventProviderTraceListener записывает в систему трассировки событий Windows (Event Tracing for Windows — ETW)
  • WebPageTraceListener выводит на веб-страницу ASP.NET

Ни один из этих прослушивателе не отображает диалоговое окно при вызове Fail, это делает только DefaultTraceListener.

// Удалить стандартный прослушиватель, очистив коллекцию прослушивателей:

Trace.Listeners.Clear();

// Добавить средство записи в файл trace.txt:

Trace.Listeners.Add (new TextWriterTraceListener («trace.txt»));

// Добавит средство записи в консоль:

System.IO.TextWriter tw = Console.Out;

Trace.Listeners.Add (new TextWriterTraceListener (tw));

// Добавить средство записи в журнал событий Windows:

if (!EventLog.SourceExists («DemoApp»))

  EventLog.CreateEventSource («DemoApp», «Application»);

Trace.Listeners.Add (new EventLogTraceListener («DemoApp»));

В случае журнала событий Windows сообщения, отправляемые с помощью Write, Fail или Assert, записываются как сведения, а сообщения методов TraceWarning и TraceError записываются как предупреждения или ошибки.

Каждый экземпляр TraceListener имеет свойство Filter и TraceFilter, с помощью которых можно управлять, будет ли сообщение записано в этот прослушиватель. Для этого необходимо создать экземпляр классов EventTypeFilter или SourceFilter (производных от TraceFilter) или создать свой класс, наследующий от TraceFilter и переопределить в нем метод ShouldTrace.

В TraceListener также определены свойства IndentLevel и IndentSize для управления отступами и свойство TraceOutputOptions для записи дополнительных данных:

TextWriterTraceListener tl = new TextWriterTraceListener (Console.Out);

tl.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Callstack;

// Это применяется при использовании метода Trace:

Trace.TraceWarning («Orange alert»);

DiagTest.vshost.exe Warning: 0 : Orange alert

DateTime=20070308T05:57:13.6250000Z

Callstack= at System.Environment.GetStackTrace(Exception e, Boolean

needFileInfo)

at System.Environment.get_StackTrace() at ...

Прослушиватели, которые записывают данные в поток, кэшируются. По этой причине данные не появляются в потоке немедленно, а также поток перед завершением приложения должен быть закрыт, или хотя бы сброшен, чтоб не потерять данные в кэше. Для этой цели классы Trace и Debug содержат статические методы Close и Flush, которые вызывают Close и Flush во всех прослушивателях (а они в свою очередь закрывают или сбрасывают все потоки). Метод Close вызывает метод Flush, закрывает файловые дескрипторы и предотвращает дальнейшую запись.

Классы Trace и Debug также определяют свойство AutoFlush, которое если равно true вызывает Flush после каждого сообщения.

Fail и Assert

Классы Debug и Trace содержат методы Fail и Assert.

Метод Fail отправляет сообщения каждому TraceListener:

Debug.Fail («File data.txt does not exist!»);

Метод Assert вызывает Fail если аргумент типа bool равен false. Это называется созданием утверждения и указывает на ошибку, если оно нарушено. Можно также создать необязательное сообщение об ошибке:

Debug.Assert (File.Exists («data.txt»), «File data.txt does not exist!»);

var result = ...

Debug.Assert (result != null);

Методы Write, Fail и Assert также могут принимать категорию в виде строки ,которая может быть использована при обработке вывода.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Обновление пакета office 2003 kb907417 ошибка 0x80096004 как исправить
  • Обозначение ошибок на панели приборов бмв е90