前陣子花了點時間在為開發中的產品加強除錯的功能,想要讓開發上發生的問題能直接在產品上就一目而然的看到,而不用另行開啟DebugView或是Log來看。簡單地說想要為產品加上類似是Visual Studio的輸出視窗,或者是DebugView類似的功能,能夠很即時的偵測並顯示出系統發出的Debug或是Trace訊息。為了達到這個需求,筆者用內建的TraceListener簡單的試做了一下,這篇隨手紀錄一下。
要達到類似DebugView的效果,代表著我們必須要能擷取到Debug.WriteLine或是Trace.WriteLine的訊息,為此我們必須要建立一個TraceListener,繼承自DefaultTraceListener,並覆寫它的WriteLine方法。在覆寫的WriteLine方法中我們可以將收到的訊息做些處理,像是把它顯示到ListBox之類的。
public class ListBoxLogTraceListener : DefaultTraceListener { private ListBox m_ListBox { get; set; }
/// /// Initializes a new instance of the class. /// /// The list box. public ListBoxLogTraceListener(ListBox listBox) { m_ListBox = listBox; }
/// /// Writes the output to the OutputDebugString function and to the method, followed by a carriage return and line feed ( ). /// /// The message to write to OutputDebugString and . /// /// /// /// public override void WriteLine(string message) { if (!m_ListBox.Visible) return;
if (m_ListBox.InvokeRequired) { m_ListBox.BeginInvoke(new MethodInvoker( delegate { WriteLine(message); } )); return; }
m_ListBox.Items.Add(string.Format("{0} {1}", DateTime.Now, message)); } }
TraceListener類別撰寫完畢,可以透過Debug.Listeners.Add或是Trace.Listeners.Add將撰寫的TraceListener類別加入,當我們程式中有用到Debug.WriteLine或是Trace.WriteLine時就會連帶觸發我們撰寫的TraceListener,藉此滿足我們想要達到的效果。
… //Debug.Listeners.Add(new ListBoxLogTraceListener(listBox1)); Trace.Listeners.Add(new ListBoxLogTraceListener(listBox1)); … Debug.WriteLine(“Debug msg…”); … Trace.WriteLine(“Trace msg…”); …
這邊附上較為完整的測試範例:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;
namespace WindowsFormsApplication6 { public partial class Form1 : Form { public Form1() { InitializeComponent(); //Debug.Listeners.Add(new ListBoxLogTraceListener(listBox1)); Trace.Listeners.Add(new ListBoxLogTraceListener(listBox1)); }
private void button1_Click(object sender, EventArgs e) { Debug.WriteLine(“Debug msg…”); }
private void button2_Click(object sender, EventArgs e) { Trace.WriteLine(“Trace msg…”); } }
public class ListBoxLogTraceListener : DefaultTraceListener { private ListBox m_ListBox { get; set; }
/// /// Initializes a new instance of the class. /// /// The list box. public ListBoxLogTraceListener(ListBox listBox) { m_ListBox = listBox; }
/// /// Writes the output to the OutputDebugString function and to the method, followed by a carriage return and line feed ( ). /// /// The message to write to OutputDebugString and . /// /// /// /// public override void WriteLine(string message) { if (!m_ListBox.Visible) return;
if (m_ListBox.InvokeRequired) { m_ListBox.BeginInvoke(new MethodInvoker( delegate { WriteLine(message); } )); return; }
m_ListBox.Items.Add(string.Format("{0} {1}", DateTime.Now, message)); } } }
運行起來我們可以看到它能偵測並顯示系統發出的Debug或是Trace訊息,在產品的除錯上會方便許多。