zoukankan      html  css  js  c++  java
  • .NET下一种简单的调试诊断方法

    .NET下,我们可以借助于DebugTrace类对程序的执行过程进行跟踪、断点、调试、日志记录等,从而可以快速定位和排除程序故障。同时.Net提供的几个TraceListener类可以方便灵活的让我们选择信息的输出方式:日志文件,事件日志等等,但有的时候我们需要实时跟踪调试信息的输出,就像IDE的调试窗口输出,或者类似HTTPWATCH的输出。比如我们在窗体上放一个Text控件,希望通过这个控件实时查看调试信息的输出。那么能否将DebugTrace类的输出定向到这个控件中呢?答案是肯定的,通过继承TraceLister类来实现,下面的代码将调试信息输出到RichTextBox中:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.Windows.Forms;

    namespace MyTraceListenerTesting
    {
        
    class MyTraceListener:TraceListener
        
    {
            
    private RichTextBox _richTextBox = null;

            
    public MyTraceListener(RichTextBox richTextBox)
            
    {
                
    this._richTextBox = richTextBox;
                
    this.NeedIndent = true;
            }


            
    private delegate void WriteDelegate(string message);
            
    private void WriteImpl(string message)
            
    {
                
    if (this.NeedIndent)
                
    {
                    
    this.WriteIndent();
                    
    this.NeedIndent = true;
                }

                
    this._richTextBox.AppendText(message);
                
    this._richTextBox.Select(this._richTextBox.Text.Length, 0);
                
    this._richTextBox.ScrollToCaret();
            }


            
    public override void Write(string message)
            
    {
                
    //This is for thread safety
                this._richTextBox.Invoke(new WriteDelegate(this.WriteImpl), new object[] { message });
            }


            
    public override void WriteLine(string message)
            
    {
                
    this.Write(message + Environment.NewLine);
            }

        }

    }

    通过上述代码可以看出,其实实现自定义的TraceLister是非常方便的,我们可以方便的根据自己的需要将日志信息输出到不同的目标位置。

    测试程序如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;

    namespace MyTraceListenerTesting
    {
        
    public partial class Form1 : Form
        
    {
            
    public Form1()
            
    {
                InitializeComponent();
            }


            
    private void f1()
            
    {
                
    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                Debug.WriteLine(
    "Enter f1 by thread " + id.ToString());
                Debug.Indent();
                
    this.f2();
                Debug.Unindent();
                Debug.WriteLine(
    "Leave f1 by thread " + id.ToString());
            }

            
    private void f2()
            
    {
                
    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                Debug.WriteLine(
    "Enter f1 by thread " + id.ToString());
                Debug.Indent();
                
    for (int i = 0; i < 100; i++)
                
    {
                    Debug.WriteLine(
    "Working inside step "+i.ToString()+"by thread " + id.ToString());
                    System.Threading.Thread.Sleep(
    20);
                }

                Debug.Unindent();
                Debug.WriteLine(
    "Leave f1 by thread " + id.ToString());
            }

            
    private void button1_Click(object sender, EventArgs e)
            
    {

                
    this.f1();
            }


            
    private void Form1_Load(object sender, EventArgs e)
            
    {
                Debug.Listeners.Add(
    new MyTraceListener(this.richTextBox1));
            }

        }

    }


    目前从其它线程单独调用Debug.WriteLine是没有问题的,可以正确的将信息写入界面线程的控件中,但是当多个线程同时调用Debug.WriteLine的时候,会出现死锁现象,关于TraceListener的线程安全如何处理目前还不是很清楚,需要进一步完善。

    这篇文章的产生基于这样的原因:一个程序因为过于庞大复杂,需要详细记录日志以便于操作,开始的时候采用了EnterpriseLibrary,效果确实好,非常方便,但后来提出程序可能要向PDA平台迁移,因此果断舍弃EnterpriseLibrary,决定采用其他方法,经过一番考察后决定采用系统自带的Debug类和Trace类,遗憾的是Trace类只提供了Assert方法,就是说在Release版本中是无法记录调试信息的,只有在DEBUG模式下面上述代码才能生效,但作为一个折中,基本上是满足项目要求了。

  • 相关阅读:
    数组 例题解析
    第六章 数组
    循环控制 例题解析
    第五章 循环控制
    第四章 选择结构程序设计
    第三章 数据的输入与输出
    第一章 程序设计及C语言概述
    C 字符串类型例题讲解与实现字符串库函数
    0XX_javascript核心
    012品优购03
  • 原文地址:https://www.cnblogs.com/swnuwangyun/p/686289.html
Copyright © 2011-2022 走看看