C# Debug

语法、IDE环境使用、Debug方法是学习一门语言的最少必须技能,本文总结C#中的最常用调试方法

一、 断点

如下图所示在欲插入断点的地方右键》断点》插入断点(或在行号左边点击)可在选中语句上插入断点:

image_thumb2

Debug模式下程序运行到断点所在语句时会阻塞在该语句上,如下图所示

image_thumb3

此时可以通过工具栏上“逐语句”、“逐过程”、“跳出”即image_thumb41来进行调试,调试期间光标放在变量上可以显示变量的当前值。

二、 跟踪点

在图1中,不仅可以插入断点,也可插入跟踪点,跟踪点是一种特殊的断点,可以配置为满足一定条件后才命中该断点,并可以将重要信息输出到Output窗口,类似于Debug.WriteLine(),它实际上是输出调试信息且不修改代码的一种方式。

image_thumb4

根据配置不同跟踪点有如下三种形状,从上到下依次为

  • 输出信息并阻塞
  • 输出信息不阻塞
  • 条件性阻塞并输出信息

image_thumb5

三、 Debug与Trace类记录调试信息

//System.Diagnostics.Debug类与System.Diagnostics.Trace可用于记录并输出调试信息
System.Diagnostics.Debug.Write("info");
System.Diagnostics.Debug.WriteIf(true, "info");
System.Diagnostics.Debug.WriteLine("info");
System.Diagnostics.Debug.WriteLineIf(true, "info");

//将info记录到监听器和VS的Output窗口

System.Diagnostics.Debug.Assert(true, "info");

System.Diagnostics.Debug类与System.Diagnostics.Trace与Log4Net相对比,使用非常简单,并且高度可视化实时监测。如果使用Log4Net等日志框架,需要进行各种繁杂的配置,不花上几天时间难以掌握这套框架。虽然Log4Net等日志框架功能强大,但是目前为止我需要的功能System.Diagnostics.Debug类与System.Diagnostics.Trace完全能满足。

3.1 配置监听器(Listeners)

Debug与Trace的监听器(Listeners)是可以自定义的,以下是MSDN原文描述:

The listeners produce formatted output from the debug output. By default, the collection contains an instance of the DefaultTraceListener class. To remove the default listener, call the Remove method, and pass it the instance of the DefaultTraceListener. To redirect output to the console window, add an instance of the ConsoleTraceListener. To redirect output to a file or stream, add an instance of the TextWriterTraceListener. The Listeners collection is shared by both the Debug and the Trace classes; adding a trace listener to either class adds the listener to both.

具体添加一个Listener方法如下:

        /// <summary>
        /// 添加控制台监听器
        /// 添加该监听器后程序运行期间将会跳出控制台窗口显示调试信息
        /// </summary>
        public static void AddConsoleTraceListener(bool useErrorStream)
        {
            ConsoleTraceListener t = new ConsoleTraceListener(useErrorStream);
            System.Diagnostics.Debug.Listeners.Add(t);
            System.Diagnostics.Debug.AutoFlush = true;
        }

        /// <summary>
        /// 添加日志文件监听器
        ///添加该监听器后程序运行时会将调试信息写入exe所在目录的.log文件中
        /// </summary>
        public static void AddTextWriterTraceListener()
        {
            TextWriterTraceListener t = new TextWriterTraceListener(FileName);
            System.Diagnostics.Debug.Listeners.Add(t);
            System.Diagnostics.Debug.AutoFlush = true;
        }

实际上也可以通过配置文件添加与配置

<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <add name="myListener"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="TextWriterOutput.log" />
        <remove name="Default" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>


3.2 利用DebugView监听调试信息

在生成exe后,直接双击exe运行,则Debug与Trace输出的调试信息可以直接在DebugView中看到。在DebugView可以通过filter查看自己感兴趣的调试信息(你可能会看到很多程序都在向这里写入调试信息)。

image_thumb7

软件捕获的是exe直接运行时,抛出的信息,而不是Visual Studio调试时的,因此只适合在你的软件已经部署以后用来查看软件运行中抛出的调试信息,相当于VS Output窗口替代品。

关于DebugView详细介绍可以参考

DebugView调试入门篇

http://blog.csdn.net/jiankunking/article/details/44984487

https://www.cnblogs.com/hbccdf/p/csharp_debug_induction.html

DebugView下载地址

https://docs.microsoft.com/zh-cn/sysinternals/downloads/debugview

3.3 System.Diagnostics.Debug类与System.Diagnostics.Trace类的区别

3.3.1 条件编译符

开发产品的时候,为了追踪代码运行状态我们会加入一些用于输出调试信息的代码,如System.Diagnostics.Debug.WriteLine("info")、Console.WriteLine等。但是产品发布的时候,我们不需要这些调试信息和调试代码,这就需要通过条件编译符来实现。即在debug模式和release模式下选择性编译某些代码。条件编译符另外一个最常见到的地方是跨平台程序的代码中,即根据平台不同条件性的编译不同的代码。

C#中通过

· 给方法加上ConditionalAttribute特性来控制代码的编译

· 使用#if..#else..#endif,来控制代码的编译

来实现条件编译

3.3.2 Debug类与Trace类区别

Debug类与Trace类的差别就在于条件编译符不同,Debug类必须在定义了名为“DEBUG”的宏的条件下才会被编译,而Trace必须在定义了名为“TRACE”的宏的条件下才会被编译,而默认条件下VS在debug模式下会定义“DEBUG”与“TRACE”宏,在release模式下只定义“TRACE”宏。因此就可以理解Debug类只能在Debug模式下执行,在Release模式下无效果,而Trace类在Debug和Release模式下都可以执行。Debug类只能在Debug模式下执行,在Release模式下无效果,而Trace类在Debug和Release模式下都可以执行。image_thumb9

posted @ 2018-02-24 16:40  蛮哥哥  阅读(6735)  评论(0编辑  收藏  举报