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模式下面上述代码才能生效,但作为一个折中,基本上是满足项目要求了。

  • 相关阅读:
    SVN服务器搭建(一)
    排序算法二:冒泡排序
    【LeetCode】136. Single Number
    【LeetCode】217. Contains Duplicate
    【LeetCode】189. Rotate Array
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】26. Remove Duplicates from Sorted Array
    【LeetCode】20. Valid Parentheses
    【LeetCode】680. Valid Palindrome II
    【LeetCode】345. Reverse Vowels of a String
  • 原文地址:https://www.cnblogs.com/swnuwangyun/p/686289.html
Copyright © 2011-2022 走看看