Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Диагностика и мониторинг






Рассмотрим некоторые средства языка C# и платформы.NET, облегчающие диагностику проблем и мониторинг поведения приложения.

Описание средств диагностики начнём с условной компиляции, выполняемой при помощи специальных директив препроцессора. Директива #define служит для перевода символа условной компиляции в состояние «определён». Символом условной компиляции может служить любой идентификатор или ключевое слово, за исключением true или false. Директива #undef переключает символ условной компиляции в состояние «не определён». Обе директивы должны располагаться в самом начале файла с исходным кодом и могут повторяться произвольное количество раз.

Директивы #if и #endif позволяют задать в исходном коде регион, который компилируется, только если символ условной компиляции, указанный после #if, определён.

#define TESTMODE

using System;

 

public class Program

{

public static void Main()

{

#if TESTMODE

Console.WriteLine(" In test mode! ");

#endif

}

}

Внутри региона #if – #endif можно применять директивы #else, #elif (это эквивалент #else #if), а символы условной компиляции после #if комбинировать при помощи операций & &, || и!.

#define TESTMODE

#define V2

 

using TestType =

#if V2 & & TESTMODE

MyCompany.GadgetV2;

#else

MyCompany.Gadget;

#endif

Заметим, что символ условной компиляции можно определить не только с помощью #define, но и указав ключ компилятора командной строки /define или используя окно свойств проекта в Visual Studio (в этих случаях символ считается определённым не в отдельном файле, а во всех файлах проекта). Visual Studio назначает в отладочной конфигурации проекта символы условной компиляции DEBUG и TRACE, а в выпускной конфигурации – только символ TRACE.

Метод класса или структуры, который возвращает значение void, может быть помечен атрибутом [Conditional] с указанием символа условной компиляции. Если символ не определён, компилятор исключит из кода все вызовы помеченного метода.

[Conditional(" TESTMODE")]

private void WriteInLog(string message)

{

Console.WriteLine(message);

}

Атрибутом [Conditional] может быть помечен и класс атрибута. В этом случае помеченный атрибут применяется к своей цели, только если указанный символ условной компиляции определён.

При мониторинге работы программы полезным оказывается возможность вывода и фиксации различных диагностических сообщений. Для этой цели можно применить статические классы Debug и Trace из пространства имён System.Diagnostics. Эти классы похожи, но все методы класса Debug помечены атрибутом [Conditional(" DEBUG")], а все методы класса Trace – атрибутом [Conditional(" TRACE")]. Классы Debug и Trace содержат статические методы вывода сообщений Write(), WriteLine(), WriteIf(), Fail() и Assert(). В классе Trace определены дополнительные методы TraceInformation(), TraceWarning() и TraceError().

// примеры вызова методов у классов Debug и Trace

Debug.WriteLine(" Debug message");

Debug.WriteIf(5 > 2, " Correct condition");

Debug.Fail(" Error in code");

Debug.Assert(3 < 2, " Error in condition");

Trace.TraceInformation(" Info");

Классы Debug и Trace имеют свойство Listeners, содержащее коллекцию слушателей – объектов классов, производных от TraceListener. Слушатели ответственны за обработку содержимого, генерируемого методами вывода сообщений. По умолчанию коллекция Listeners включает одного слушателя – объект класса DefaultTraceListener. Этот слушатель записывает сообщения в окно отладчика Visual Studio, а при вызове метода Fail() или нарушении условия в методе Assert() выводит диалоговое окно для подтверждения выполнения программы. Данное поведение можно изменить, удалив слушатель или добавив один или несколько собственных слушателей. Слушатель можно создать, унаследовав от класса TraceListener или воспользоваться одним из готовых классов:

TextWriteTraceListener – пишет в поток, или в TextWriter, или в файл. Имеет подклассы ConsoleTraceListener, DelimitedListTraceListener, XmlWriterTraceListener, EventSchemaTraceListener.

EventLogTraceListener – пишет в журнал событий Windows. При этом сообщения, выводимые методами TraceWarning() и TraceError(), выводятся как предупреждения и ошибки соответственно.

EventProviderTraceListener – пишет в подсистему ETW в Windows Vista.

WebPageTraceListener – пишет на веб-страницу ASP.NET.

// удаляем слушатель по умолчанию

Trace.Listeners.Clear();

 

// добавляем слушатель для записи в конец файла

Trace.Listeners.Add(new TextWriterTraceListener(" trace.txt"));

 

// настраиваем журнал событий Windows

if (! EventLog.SourceExists(" DemoApp"))

{

EventLog.CreateEventSource(" DemoApp", " Application");

}

 

// и добавляем соответствующий слушатель

Trace.Listeners.Add(new EventLogTraceListener(" DemoApp"));

 

// пишем несколько сообщений в файл и журнал событий

Trace.WriteLine(" message");

Trace.TraceError(" error");

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

var listener = new TextWriterTraceListener(" trace.txt");

listener.Filter = new SourceFilter(" Program");

listener.IndentSize = 4;

Для слушателей, которые пишут информацию в кэшируемый поток (например, слушатель TextWriteTraceListener), рекомендуется перед окончанием работы приложения вызывать методы Close() или Flash(). Такие же методы есть у классов Debug и Trace. Если у этих классов установить свойство AutoFlash в true, то метод Flash() будет вызываться после каждого сообщения.

Отметим, что настройка слушателей может быть выполнена не только программно, но и декларативно – с использование конфигурационного файла приложения (секция < system.diagnostics>):

< configuration>

< system.diagnostics>

< trace autoflush=" true" indentsize=" 2" >

< listeners>

< add name=" lst"

type=" System.Diagnostics.TextWriterTraceListener,

System, Version=1.0.3300.0, Culture=neutral,

PublicKeyToken=b77a5c561934e089"

initializeData=" MyListener.log"

traceOutputOptions=" ProcessId, Timestamp" />

< /listeners>

< /trace>

< /system.diagnostics>

< /configuration>

Ещё один полезный класс из пространства имён System.Diagnostics – класс Stopwatch. Он предоставляет набор методов и средств, которые можно использовать для точного измерения затраченного времени. В типовом сценарии использования у экземпляра Stopwatch вызывается метод Start(), затем – метод Stop(), а затраченное время проверяется при помощи свойства Elapsed.

// замерим скорость подсчёта факториала 10000

var sw = new Stopwatch();

sw.Start();

BigInteger factorial = 1;

for (int i = 2; i < 10000; i++)

{

factorial *= i;

}

sw.Stop();

Console.WriteLine(sw.Elapsed); // 00: 00: 00.0909346






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.