Visual C 锐化中的跟踪和调试

本文介绍如何在 Visual C# 中跟踪和调试,并提供一些说明相关信息的示例步骤。

原始产品版本: Visual C#
原始 KB 数: 815788

总结

有关本文的 Microsoft Visual Basic .NET 版本,请参阅 Visual Basic .NET 中的“使用跟踪”和“调试”类。

本文介绍 .NET Framework 类库命名空间系统。 诊断并描述如何使用 DebugTrace 类。 这些类在 .NET Framework 中可用。 可以使用这些类在应用程序开发期间或部署到生产环境期间提供有关应用程序性能的信息。 这些类只是 .NET Framework 中提供的检测功能的一部分。

要求

以下列表概述了所需的推荐硬件、软件、网络基础结构和服务包:

  • Microsoft Windows
  • Microsoft Visual C#

本文还假定你熟悉程序调试。

技术说明

“使用调试类创建示例”部分中的步骤演示如何创建一个控制台应用程序,该应用程序使用Debug该类提供有关程序执行的信息。

运行程序时,可以使用类的方法 Debug 生成有助于监视程序执行序列、检测故障或提供性能度量信息的消息。 默认情况下,类 Debug 生成的消息将显示在 Visual Studio 集成开发环境的“输出”窗口中(IDE)。

示例代码使用 WriteLine 该方法生成后跟行终止符的消息。 使用此方法生成消息时,每个消息将显示在“输出”窗口中的单独行上。

使用 Assert 类的方法 Debug 时,仅当指定条件的计算结果为 false 时,“输出”窗口才会显示消息。 该消息也会显示在用户的模式对话框中。 该对话框包括消息、项目名称和 Debug. Assert 语句编号。 该对话框还包括以下三个命令按钮:

  • 中止: 应用程序停止运行。

  • 重试: 应用程序进入调试模式。

  • 忽略: 应用程序继续进行。 用户必须先单击其中一个按钮,然后应用程序才能继续。

还可以将类的 Debug 输出定向到“输出”窗口以外的目标。 该 Debug 类具有包含 Listener 对象的侦听器集合。

每个侦听器对象监视 Debug 输出并将输出定向到指定的目标。

侦听器集合中的每个侦听器都接收类生成的任何输出 Debug 。 使用 TextWriterTraceListener 类定义 Listener 对象。 可以通过类的构造函数指定类的目标 TextWriterTraceListener

一些可能的输出目标包括:

  • 使用 System.Console.Out 属性的控制台窗口。
  • 使用 System.IO.File.CreateText("FileName.txt") 语句的文本(.txt)文件。 创建TextWriterTraceListener对象后,必须将对象添加到 .Debug 要接收 Debug 输出的侦听器集合。

使用 Debug 类创建示例

  1. 启动 Visual Studio 或 Visual C# Express Edition。

  2. 创建名为 conInfo 的新 Visual C# 控制台应用程序项目。 类 1 是在 Visual Studio .NET 中创建的。 Program.cs是在 Visual Studio 2005 中创建的。

  3. 在 Class1 或 Program.cs 顶部添加以下命名空间。

    using System.Diagnostics;
    
  4. 若要初始化变量以包含有关产品的信息,请将以下声明语句添加到 Main 方法:

    string sProdName = "Widget";
    int iUnitQty = 100;
    double dUnitCost = 1.03;
    
  5. 指定类生成为方法的第一个输入参数 WriteLine 的消息。 按 Ctrl+Alt+O 组合键以确保“输出”窗口可见。

    Debug.WriteLine("Debug Information-Product Starting ");
    
  6. 若要提高可读性,请使用该方法 Indent 在“输出”窗口中缩进后续消息:

    Debug.Indent();
    
  7. 若要显示所选变量的内容,请使用 WriteLine 如下所示的方法:

    Debug.WriteLine("The product name is " + sProdName);
    Debug.WriteLine("The available units on hand are" + iUnitQty.ToString());
    Debug.WriteLine("The per unit cost is " + dUnitCost.ToString());
    
  8. 还可以使用 WriteLine 该方法显示现有对象的命名空间和类名称。 例如,以下代码在“输出”窗口中显示 System.Xml.XmlDocument 命名空间:

    System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
    Debug.WriteLine(oxml);
    
  9. 若要组织输出,可以将类别作为方法的 WriteLine 可选第二个输入参数包含在内。 如果指定类别,“输出”窗口消息的格式为“category: message”。例如,以下代码的第一行在“输出”窗口中显示“字段:产品名称为小组件” :

    Debug.WriteLine("The product name is " + sProdName,"Field");
    Debug.WriteLine("The units on hand are" + iUnitQty,"Field");
    Debug.WriteLine("The per unit cost is" + dUnitCost.ToString(),"Field");
    Debug.WriteLine("Total Cost is " + (iUnitQty * dUnitCost),"Calc");
    
  10. 仅当指定的条件使用 WriteLineIf 类的方法 Debug 计算结果为 true 时,“输出”窗口才能显示消息。 要计算的条件是该方法的第一个输入参数 WriteLineIf 。 第二个参数是仅在第一个参数 WriteLineIf 中的条件计算结果为 true 时显示的消息。

    Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
    Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");
    
  11. 使用类的 Debug Assert 方法,以便仅当指定条件的计算结果为 false 时,“输出”窗口才会显示消息:

    Debug.Assert(dUnitCost > 1, "Message will NOT appear");
    Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");
    
  12. TextWriterTraceListener 控制台窗口 (tr1) 和名为 Output.txt (tr2) 的文本文件创建对象,然后将每个对象添加到调试侦听器集合:

    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);
    
  13. 若要提高可读性,请使用 Unindent 该方法删除类生成的后续消息 Debug 的缩进。 一 Indent 起使用和 Unindent 方法时,读取器可以将输出区分开来作为组。

    Debug.Unindent();
    Debug.WriteLine("Debug Information-Product Ending");
    
  14. 若要确保每个 Listener 对象接收其所有输出,请调用类缓冲区的 Debug Flush 方法:

    Debug.Flush();
    

使用跟踪类

还可以使用该 Trace 类生成监视应用程序执行的消息。 和TraceDebug类共享大多数相同的方法来生成输出,包括:

  • WriteLine
  • WriteLineIf
  • 订货单
  • Unindent
  • Assert
  • 刷新

可以在 Trace 同一应用程序中单独使用和 Debug 类。 在调试解决方案配置项目中,输出都TraceDebug处于活动状态。 项目生成这两个类到所有 Listener 对象的输出。 但是,发布解决方案配置项目仅生成类 Trace 的输出。 发布解决方案配置项目忽略任何 Debug 类方法调用。

Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();

Trace.WriteLine("The product name is "+sProdName);
Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");

Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");

Trace.Flush();

Console.ReadLine();

验证它是否正常工作

  1. 确保调试是当前解决方案配置。

  2. 如果解决方案资源管理器窗口不可见,请按 Ctrl+Alt+L 键组合以显示此窗口。

  3. 右键单击 conInfo,然后单击“ 属性”。

  4. 在 conInfo 属性页的左窗格中,在“配置”文件夹下,确保箭头指向“调试”。

    注意

    在 Visual C# 2005 和 Visual C# 2005 Express Edition 中,单击 conInfo 页面中的“调试”。

  5. “配置”文件夹上方的“配置”下拉列表框中,单击“活动”(调试)“调试”,然后单击“确定”。 在 Visual C# 2005 和 Visual C# 2005 Express Edition 中,在“调试”页的“配置”下拉列表框中单击“活动”(调试)“调试”,然后单击“文件”菜单上的保存”。

  6. Ctrl+Alt+O 显示 “输出 ”窗口。

  7. 按 F5 键运行代码。 出现断言失败对话框时,单击“忽略”。

  8. 控制台 窗口中,按 Enter。 程序应完成,“ 输出 ”窗口应显示如下所示的输出:

    Debug Information-Product Starting
    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    System.Xml.XmlDocument
    Field: The product name is Widget
    Field: The units on hand are100
    Field: The per unit cost is1.03
    Calc: Total Cost is 103
    This message WILL appear
    ---- DEBUG ASSERTION FAILED ----
    ---- Assert Short Message ----
    Message will appear since dUnitcost < 1 is false
    ---- Assert Long Message ----
    
    at Class1.Main(String[] args) <%Path%>\class1.cs(34)
    
    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name isWidget
    This message WILL appear
    Trace Information-Product Ending
    
  9. 控制台窗口和Output.txt文件应显示以下输出:

    The product name is Widget
    The available units on hand are 100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name is Widget
    This message WILL appear
    Trace Information-Product Ending
    

注意

Output.txt文件位于 conInfo 可执行文件(conInfo.exe)所在的同一目录中。 通常,这是存储项目源的 \bin 文件夹。 默认情况下,该属性为 C:\Documents and Settings\User login\My Documents\Visual Studio Projects\conInfo\bin。 在 Visual C# 2005 和 Visual C# 2005 Express Edition 中,Output.txt文件位于文件夹中: C:\Documents and Settings\User login\My Documents\Visual Studio 2005\Projects\conInfo\conInfo\bin\Debug

完整代码列表

using System;
using System.Diagnostics;

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        string sProdName = "Widget";
        int iUnitQty = 100;
        double dUnitCost = 1.03;
        Debug.WriteLine("Debug Information-Product Starting ");
        Debug.Indent();
        Debug.WriteLine("The product name is "+sProdName);
        Debug.WriteLine("The available units on hand are"+iUnitQty.ToString());
        Debug.WriteLine("The per unit cost is "+ dUnitCost.ToString());

        System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
        Debug.WriteLine(oxml);

        Debug.WriteLine("The product name is "+sProdName,"Field");
        Debug.WriteLine("The units on hand are"+iUnitQty,"Field");
        Debug.WriteLine("The per unit cost is"+dUnitCost.ToString(),"Field");
        Debug.WriteLine("Total Cost is "+(iUnitQty * dUnitCost),"Calc");

        Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
        Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");

        Debug.Assert(dUnitCost > 1, "Message will NOT appear");
        Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");

        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);

        Debug.WriteLine("The product name is "+sProdName);
        Debug.WriteLine("The available units on hand are"+iUnitQty);
        Debug.WriteLine("The per unit cost is "+dUnitCost);
        Debug.Unindent();
        Debug.WriteLine("Debug Information-Product Ending");
        Debug.Flush();

        Trace.WriteLine("Trace Information-Product Starting ");
        Trace.Indent();

        Trace.WriteLine("The product name is "+sProdName);
        Trace.WriteLine("The product name is"+sProdName,"Field" );
        Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
        Trace.Assert(dUnitCost > 1, "Message will NOT appear");

        Trace.Unindent();
        Trace.WriteLine("Trace Information-Product Ending");

        Trace.Flush();

        Console.ReadLine();
    }
}

疑难解答

  • 如果解决方案配置类型为 Release,则 Debug 忽略类输出。

  • 为特定目标创建 TextWriterTraceListener 类后, TextWriterTraceListener 接收来自 Trace 该类和类的 Debug 输出。 无论使用Add类的方法DebugTrace还是将类添加到TextWriterTraceListenerListeners类,都会发生这种情况。

  • 如果在类DebugTrace为同一Listeners目标添加对象,则无论输出是DebugTrace还是生成输出,每行输出都会重复。

    TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
    Debug.Listeners.Add(myWriter);
    
    TextWriterTraceListener myCreator = new TextWriterTraceListener(System.Console.Out);
    Trace.Listeners.Add(myCreator);
    

参考