C#中的跟踪

 

今天开始看C#高级编程书中的跟踪和事件这一章了,可是书上的内容感觉上很抽象。google了一下这部分的内容,找到的都是关于Debug类和 Trace类的信息,看了微软提供的帮助和支持文档,感觉这两个类用起来要简单多了。而且因为有代码,理解起来也容易。所以关于跟踪就从这两个类入手。 Debug类和Trace类是.NET1.0中提供的类,他们的用法基本相同,只是Debug是在Debug本版本下使用,在Release版本下不会生 成代码,而Trace在默认情况下是打开的,也就是说在Debug版本和Release版本下都会生成代码。    

DebugTrace类中共有的成员有:

1.       Assert()当条件不成立时弹出模式对话框,显示错误信息,这个函数有三个版本的重载,MSDN上解释如下:

a)         Assertboolean 条件为false,输出调用堆栈信息。

b)        AssertbooleanString 条件为false,输出消息。

c)        AssertbooleanStringString 条件为false,输出两条消息。

2.       WriteLine()函数将指定消息输出到Listenters集合中对应的对象位置,这个函数有四个重载版本。MSDN上解释:

a)         WriteLineobject 将对象的ToString方法值写入Listeners集合中的跟踪监听器中。由于没有重载ToString方法的类中,ToString的方法会返回这个类所在的命名空间和类名,所以微软的帮助文档中竟然把这个当成了这个函数的特征来使用,微软的文档出现这种问题真是不该啊!

b)        WriteLinestring 将字符串写入Listenters集合中的跟踪监听器。

c)        WriteLineobjectstring 将类别名称和对象的ToString方法值写入Listenters集合中的跟踪监听器中.

d)        WriteLinestringstring 将类别名称和消息写入Listenters集合中的跟踪器中。这个函数的用法类似c),其中类别名称为第二个参数。如:WriteLine(“123”, “integer”);显示结果为:integer: 123

3.       还有Write, WriteIf, WriteLineIf函数的行为和WriteLine函数基本一致,只是前面两个不打印换行符,而有If后缀的函数加入了一个判断参数作为显示的条件。

4.       Indent()函数递增IndentLevel的值,IndentLevel是指缩进的意思,就像在写代码的时候总会有缩进以使代码的结构更加清晰,这里也应该是为了打印出来的调试结果更加清晰吧。这个函数对应了UnIndent()方法,和IndentSizeIndentLevel的属性值。IndentLevel表示当前缩进的级别,IndentSize表示一次缩进的空格数。这两个属性都是可读写的。

5.       Flush()函数刷新缓冲区,以使缓冲区的数据写入Listenters集合中,这个和文件的写入一样的,在写文件的时候,如果数据比较小,这些数据不会马上写到文件中,而是先存在缓冲区中,以减少读取磁盘的次数,增加性能,但是如果程序退出前没有调用Flush()或Close()函数,缓冲区中的数据就不会写入到文件中,这可以通过设置AutoFlush属性为true迫使缓冲区中的数据一旦存在就写入文件,一般在实时性要求比较高的情况下才要这样做的,因为这样无疑增加了读写磁盘的次数,降低了性能。Close()函数会刷新缓冲区,然后关闭Listenters所指向的对象连接,比如关闭已打开的文件。

6.       Fail()函数,发出指定的错误信息。它会跳出类似Assert的对话框,这是一个非模式对话框,级别比Assert低,而且可以显示详细信息(第二个参数)。

7.       Listenters属性,它是TraceListenerCollection类型(TraceSource类和TraceListener类),给类属性控制跟踪信息输出的方向,可以是控制台(add(TextWriterTraceListener(new Console.Out))),文件(add(TextWriterTraceListener(new IO.File.CreateText(“output.txt”))等。Listenters集合中的成员包括TextWriterTraceListenerDefaultTraceListenerEventLogTraceListenerWebPageTraceListener等。而TextWriterTraceListener的子类又有ConsoleTraceListener DelimitedListTraceListenerXmlWriterTraceListenerEventSchemaTraceListener。在配置文件中,由于intializeData为字符串类型,因而不能通过它来创建控制台等类型的Listeners,所以可以通过type类型来直接指定ConsoleTraceListenerListeners

 

在区别上,Debug类提供了Print()方法,类似WriteLine()方法。它有两个重载版本。

a)    Printstring msg 将后跟行结束符的消息写入Listeners集合中的跟踪侦听器中。

b)    Printstring formatobject[] 将后跟格式化字符串写入Listenters集合中的跟踪侦听器中。

 

Trace类则提供了三个方法,TraceError(), TraceInformation(), TraceWarning()将错误,信息,警告信息写入到Listeners集合对象中这三个函数都有和Print()方法一样的重载函数。他们分别会打印出对应的编码和传入的消息。
Trace类还提供了Refresh()方法,跟踪配置数据在应用程序启动时被捕获,如果在应用程序启动后更改了配置数据,则调用Refresh方法来跟新跟踪配置数据。这个方法可以改进在配置文件改变后必须重新启动应用程序的缺憾,可以在应用程序中设置一个事件,比如按钮,可以在配置文件改变时调用该方法,以使配置生效。


 

特别注意的是,以上方法都是静态方法。这两个类也是sealed类型的,而且估计不能使用构造函数,要不构造函数是静态的或是私有的。但是VS给出的提示是TraceDebug)类未定义构造函数。

 

一个小小的演示例子:

namespace DebugTrace

{

    class Program

    {

        static void Main(string[] args)

        {

            string name = "dinglifedream";

            int num = 20;

 

            TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);

            Debug.Listeners.Add(tr1);

            TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("output.txt"));

            Debug.Listeners.Add(tr2);

            EventLogTraceListener tr3 = new EventLogTraceListener();

            Debug.Listeners.Add(tr3);

 

            Debug.WriteLine("--Debug information begin!--");

            Debug.Indent();

            Debug.WriteLine("name value is : " + name, "String");

            Debug.WriteLine("number value is : " + num, "Integer");

 

            Debug.WriteLine(new Program());

            Debug.WriteLine(new String('a', 10));

 

            Debug.Unindent();

            Debug.Print("--Debug information end!--");

 

            //Debug.Fail("Error Erupted");

            Trace.TraceError("Trace Error : {0}", num);

            Trace.TraceWarning("Trace Warning");

            Trace.TraceInformation("Trace Information");

            Debug.Flush();

        }

    }

}

 

显示结果:

--Debug information begin!--

   String: name value is : dinglifedream

   Integer: number value is : 20

   DebugTrace.Program

   aaaaaaaaaa

--Debug information end!--

DebugTrace.exe Error: 0 : Trace Error : 20

 

另外,可以通过配置文件来配置Listeners,如上的配置文件可以写成:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

 <system.diagnostics>

    <trace>

      <listeners>

        <add name ="myListener" type = "System.Diagnostics.ConsoleTraceListener" />

         <add name ="myListener2" type = "System.Diagnostics.TextWriterTraceListener" initializeData="output.txt" />

      </listeners>

    </trace>

 </system.diagnostics>

</configuration>

刚开始我弄这个弄了好半天,一直以为要在代码中把Listeners的字段填充进去的,后来一直找不到和配置文件怎么关联起来,网上给出的都只是配置文件,后来才发现其实配置文件是可以直接关联的,不用有什么设置的,也不用给Listeners赋值的。第二点是可以理解的,因为对一个程序,只有一个Debug或是Trace类,所以可以直接给他赋值,但是配置文件中的类和源代码怎么没有通过语句关联呢,是这个类特殊还是其他类也可以有这样的情况,比如自定义的类?这个请有知道的高手解答!谢谢!

 

posted @ 2008-10-14 02:00  江湖飘  阅读(1959)  评论(4编辑  收藏  举报