是输出信息更加容易阅读:
有时候应用程序很复杂,为了容易理解可以格式化跟踪信息。使输出信息更加漂亮,可以使用缩排,看下面的简单代码:
public void Callee()
{
Trace.WrteLine(“Callee started”);
……//Some internal logic
Trace.WriteLine(“Initializing Buffer”);
……//Some extra internal login
Trace.WriteLine(“Exiting Callee”);
}
public void Caller()
{
Trace.Write(“Caller Called”);
…..//Some external logic
Callee();
…..//Some extral Logic
Trace.WriteLine(“Initializing Buffer”);
Trace.Write(“Exiting Caller”);
}
输出信息如下:
Caller called
Callee stared
Initializing buffer
Exiting Callee
Initializing buffer
Exiting Caller
如果方法执行前后没有显示信息,我们将被这些拷贝的初始化缓存信息所迷惑。除了信息显示不清楚。为了避免不明确,我们使用Trace类支持的缩进功能。修改的代码,使用缩进:
public void Callee()
{
Trace.indent();
Trace.WriteLine(“Callee started”);
…..//some internal logic
Trace.WriteLine(“Initializing Buffer”);
….//Some extra internal logic
Trace.WriteLine(“Exiting Callee”);
Trace.Unindent();
}
public void Caller()
{
Trace.Write(“Caller called”);
….//Some External Logic
Callee();
….//Some Extra Login
Trace.WriteLine(“Initiallizing buffer”);
Trace.Write(“Exiting Caller”);
}
输出信息如下:
Caller called
Callee started
Initializing buffer
Exiting Callee
Initializing buffer
Exiting Caller
正如你看到的,callee方法输出缩进,很容易分开不同方法的信息。可以调用Indent和Unident方法,达到分离信息的目的。
在配置文件中修改跟踪配置:
<configuration>
<system.diagnostics>
<trace indentsize = “3”/ >
</system.diagnostics>
</configuration>
------------------------------------------
调试
实际上调试和跟踪用得很普遍。Debug类中的方法有相同的名字的方法,这些方法实现了调试的功能。不同之处是在发布版本配置中是禁止使用的(这意味着不能产生二进制代码调用这些代码)。调试输出也可以在配置文件设置,请看下面:
<confuration>
<system.diagnostics>
<debug autoflush = “true” indentsize = “7”/ >
</system.diagnostics>
</confuration>
备注:调试的声明和语法和跟踪很类似。不同之处,就是把有Trace的地方替换为Debug
设置调试开关
最后讨论的主题是Switch。Switch是有一些状态的对象。可以在配置文件或者编程的时候改变状态。Switch让你创建可配置的调试跟踪代码。最好了解Switch的方法是写一个段简单代码,如下:
using System;
using System.Diagnostics;
namespace Switching
{
class SampleClass
{
//Create a Switch. It is initialized by an externally specified value
static TraceSwitch generalSwitch = new TraceSwitch(“CoolSwitch”, “Global Scope”);
static public void SampleMethod()
{
//The first message is written if the switch state is set to TraceError
if(generalSwitch.TraceError)
console.WriteLine(“TraceError message”);
//The second message is written if the switch state is set to TraceVerbose
if (generalSwitch.TraceVerbose)
Console.WriteLine(“TraceVerbose message”);
//The third message is writeen if the switch state is set to TraceWarning
if (generalSwitch.TraceWarning)
Console.WriteLine(“TreaceWarning message”);
//The fourth message is written if the switch state is set to TraceInfo
if(generalSwitch.TraceInfo)
Console.WriteLine(“TraceInfo Message”);
}
public static voidMain(string[] args)
{
//calls the sampleMethod method
SampleMethod();
}
}
}
有几个switch类:TraceSwitch和BooleanSwitch。这个例子中我们用使用TraceSwitch依照他们的状态创建输出信息。Switch状态由TraceErrror,TraceInfo,TraceVerbose和TraceWarning属性检查。这些属性检查switch状态和如果trace级别等于或大于相应的常量,那么将返回true。例如,当这个级别是2或者更大那么TraceWarning是true,下面表格是返回值:
TraceErroe | 1 |
TraceWarning | 2 |
TraceInfo | 3 |
TraceVerbose | 4 |
但是,正如我们已经说的,switch的状态可以在代码中修改,做个修改代码的范例:
using System;
using System.Diagnostics;
namespace Switching
{
class SampleClass
{
//Create a Switch. It is initialized by an externally specified value
static TraceSwitch generalSwitch = new TraceSwitch(“CoolSwitch”, “Global Scope”);
static public void SampleMethod()
{
//The first message is written if the switch state is set to TraceError
if(generalSwitch.TraceError)
console.WriteLine(“TraceError message”);
//The second message is written if the switch state is set to TraceVerbose
if (generalSwitch.TraceVerbose)
Console.WriteLine(“TraceVerbose message”);
//The third message is writeen if the switch state is set to TraceWarning
if (generalSwitch.TraceWarning)
Console.WriteLine(“TreaceWarning message”);
//The fourth message is written if the switch state is set to TraceInfo
if(generalSwitch.TraceInfo)
Console.WriteLine(“TraceInfo Message”);
}
public static voidMain(string[] args)
{
Console.WriteLine(“Before manual level set\n”);
SampleMethod();
GeneralSwitch.Level = TraceLevel.Warning;
SampleMethod();
}
}
运行程序,包含以下信息:
Before manual level set
TraceError Message
TraceWarning message
TraceInfo message
After manual level set
TraceError Message
TraceWarning Message
这些展示了改变trace switch层次。
计算性能
这部分我们将告诉你调试的花费时间。事实上,调试对于商业逻辑不起作用。但是调试代码需要花费时间。我们将计算应用程序中输出信息的花费时间。当你测试一个是建要求严格的应用程序时间,测量就很重要。看下面的代码:
using system;
using system.Diagnostics;
namespace DebugDemo
{
class PrimeNumberDetector
{
public static bool IsPrime(int n)
{
int upperbound = (int)Math.Sqrt(n);
for (int I = 2; I <= upperbound; I++)
{
Debug.WriteLine(“Processing number” + n + “, Testing with “ + i);
If((n%i) == 0)
{
Debug.WriteLine(“FAILED”);
Return false;
}
}
}
public Application
{
[STAThread]
static voidMain(string[] args)
{
for(int i = 2; i < 10000;i++)
if (PrimeNumberDetector.IsPrime(i))
Console.WriteLine(“{0} is prime number” , i);
}
}
}
程序测试2到1000个整数和输出素数。调试的目的是测试每一个输出数字,不管是否是素数。如果数字不是素数,那么输出failed.
对比测量下带调试和不带调试的时间:
可以看出调试是昂贵的—例子中花费了64%的执行时间
表
结论:
文章中描述了调试跟踪.net程序的一般方法。当然还有一些其他问题,如,条件编译我们没有做。想学到更多的东西,可以看msdn。我们希望这篇文章帮助你掌握调试跟踪.net程序的技术。