Читать в оригинале

<< Предыдущая Оглавление Следующая >>


1.2.2. Классы Debug и Trace

Атрибут условной компиляции Conditional характеризует метод, но не отдельный оператор. Иногда хотелось бы иметь условный оператор печати, не создавая специального метода, как это было сделано в предыдущем примере. Такую возможность и многие другие полезные свойства предоставляют классы Debug и Trace.

Классы Debug и Trace - это классы-двойники. Оба они находятся в пространстве имен Diagnostics, имеют идентичный набор статических свойств и методов с идентичной семантикой. В чем же разница? Методы класса Debug имеют атрибут условной компиляции с константой DEBUG, действуют только в Debug-конфигурации проекта и игнорируются в Release-конфигурации. Методы класса Trace включают два атрибута Conditional с константами DEBUG и TRACE и действуют в обеих конфигурациях.

Одна из основных групп методов этих классов - методы печати данных: Write, WriteIf, WriteLine, WriteLineIf. Методы перегружены, в простейшем случае позволяют выводить некоторое сообщение. Методы со словом If могут сделать печать условной, задавая условие печати в качестве первого аргумента метода, что иногда крайне полезно. Методы со словом Line дают возможность дополнять сообщение символом перехода на новую строку.

По умолчанию методы обоих классов направляют вывод в окно Output. Однако это не всегда целесообразно, особенно для Release-конфигурации. Замечательным свойством методов классов Debug и Trace является то, что они могут иметь много «слушателей», направляя вывод каждому из них. Свойство Listeners этих классов возвращает разделяемую обоими классами коллекцию слушателей - TraceListenerCollection. Как и всякая коллекция, она имеет ряд методов для добавления новых слушателей: Add, AddRange, Insert - и возможность удаления слушателей: Clear, Remove, RemoveAt и другие методы. Объекты этой коллекции в качестве предка имеют абстрактный класс TraceListener.

Библиотека NFCL включает три неабстрактных потомка этого класса:

DefaultTraceListener - слушатель этого класса добавляется в коллекцию по умолчанию, направляет вывод, поступающий при вызове методов классов Debug и Trace, в окно Output;

EventLogTraceListener - посылает сообщения в журнал событий Windows;

TextWriterTraceListener - направляет сообщения объектам класса TextWriter или Stream; обычно один из объектов этого класса направляет вывод на консоль, другой - в файл.

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

Помимо свойства Listeners и методов печати, классы Debug и Trace имеют и другие важные методы и свойства:

Assert и Fail, проверяющие корректность хода вычислений - о них мы поговорим особо;

Flush - метод, отправляющий содержание буфера слушателю (в файл, на консоль и так далее). Следует помнить, что данные буферизуются, поэтому применение метода Flush зачастую необходимо, иначе метод может завершиться, а данные останутся в буфере;

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

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

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

Рассмотрим пример работы, в котором отладочная информация направляется в разные каналы - окно вывода, консоль, файл:

public void Optima() {
         double x, y = 1;
         x = y - 2*Math.Sin(y);
         FileStream f = new FileStream("Debuginfo.txt", FileMode.Create, FileAccess.Write);
         TextWriterTraceListener writer1 = new TextWriterTraceListener(f);
         TextWriterTraceListener writer2 = new TextWriterTraceListener(System.Console.Out);
         Trace.Listeners.Add(writer1);
         Debug.Listeners.Add(writer2);
         Debug.WriteLine("Число слушателей:" + Debug.Listeners.Count);
         Debug.WriteLine("автоматический вывод из буфера:" + Trace.AutoFlush);
         Trace.WriteLineIf(x < 0, "Trace: " + "x= " + x.ToString() + " y = " + y);
         Debug.WriteLine("Debug: " + "x= " + x.ToString() + " y = " + y);
         Trace.Flush();
         f.Close();
}

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

Рис. 2. Три канала вывода

 



<< Предыдущая Оглавление Следующая >>