C# 線程手冊 第六章 線程調試與跟蹤 使用不同的監聽器程序


  在這部分,我們將了解如何改變默認的監聽器程序。Trace 類和Debug類暴露了監聽器集合(一系列監聽程序集合)。如果不添加任何新的監聽類,DefaultTraceListener 將指向由Visual Studio.NET 提供的調試輸出窗口。然而,.NET Framework 提供另外可以用作監聽程序的兩個類:

2012-4-24 21-22-30

  如果你需要跟蹤一個不在Visual Studio 中執行的多線程應用程序的行為,那么你需要將默認監聽器改成以上列表中的某一個。通常情況下,調試輸出窗口僅在調試過程中可用。使用這兩個類,你可以選擇將跟蹤消息寫入Windows 事件日志中或者一個文本文件中。一般來說,如果你知道你的程序運行在一個有事件日志的操作系統中的話,那么使用EventLogTraceListener 類將是最好的選擇。原因如下:

  1. 事件日志由操作系統管理;

  2. 事件日志允許管理員確定日志的安全設置;

  3. 事件日志需要使用事件日志查看器讀取。這比用Notepad 讀取的文本文件在閱讀效果上要好得多(隨着科技進步,也不盡然)。

改變默認的監聽器程序很簡單,我們來看一個例子,TraceEventLog.cs:

static void Main(string[] args)
{
    //Create a trace listener for the event log.
    EventLogTraceListener eltl = new EventLogTraceListener("TraceLog");

    //Add the event log trace listener to the collection.
    Trace.Listeners.Add(eltl);

    //Write output to the event log.
    Trace.WriteLine("Entered in Main()");
}

  首先,我們需要創建一個新的監聽器對象。在上面的例子中,為了將Windows 事件日志作為監聽器程序我們創建了一個新的EventLogTraceListener 對象。這個類的構造函數接收一個字符串作為參數,用於設置寫入記錄的日志源名稱。構造函數將會實例化一個新的EventLog 對象並自動地使用輸入參數值設置EventLog 類的Source 屬性。

  下一步是使用Add() 方法向集合中添加一個新的監聽器對象並向監聽器對象提供其引用。最后,我們可以開始寫入跟蹤消息,這些消息將被中轉給監聽程序。

  使用事件日志查看器(開始菜單->運行->輸入 eventvwr)打開Windows 事務日志, 你將在應用程序部分看到一條新的日志:

2012-4-24 21-39-50

  你可以雙擊應用程序日志中對應的記錄並檢查其中的內容:

2012-4-24 21-40-30

  上面的代碼在監聽器集合中添加了一個新的監聽器,所以你將同時在調試輸出窗口和Windows 事件日志中看到消息。如果你想移除默認的監聽器而只使用事件日志的話,你需要使用RemoveAt() 方法,如下所示:

static void Main(string[] args)
{
    //Create a trace listener for the event log.
    EventLogTraceListener eltl = new EventLogTraceListener("TraceLog");

    //Remove the default listener
    Trace.Listeners.RemoveAt(0);

    //Write output to the event log.
    Trace.WriteLine("Entered in Main()");
}

TextWriterTraceListener 類

我們將要通過檢查TextWriterTraceListener類來進一步了解監聽器。當你需要將跟蹤消息直接寫到一個文本文件中或者一個控制台應用程序中的話使用它會很有用。事實上,在創建一個TextWriterTraceListener對象過程中,你可以確定使用一個TextWriter 對象或者一個Stream 對象。使用一個Stream 對象允許你設定更多關於如何處理文件流的選項。下面的代碼片段,TraceConsole.cs, 顯示了如何在控制台中跟蹤消息:

static void Main(string[] args)
{
    //Remove the default listener.
    Trace.Listeners.RemoveAt(0);

    //Add a console listener
    Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

    //Write a trace message.
    Trace.WriteLine("Entered in Main()");

}

由於在類的構造函數中設定Console.Out 流作為監聽器,所以我們的控制台程序將顯示跟蹤消息:

2012-4-24 21-51-43

最后,讓我們看看如何添加文本日志文件作為監聽器。我們需要添加一個新的TextWriterTraceListener 對象,在構造函數中使用一個FileStream 對象。當程序結束以后,你需要使用Trace 類提供的靜態Close() 方法來顯式地關閉日志同時寫入所有消息。在下面的代碼中,Debugging.s, 使用主次線程來跟蹤消息:

static void WritingThread()
{
    //Trace an info message
    Trace.WriteLine(DateTime.Now + " - Entered WritingThread()");

    Thread.Sleep(1000);

    //Trace an info message
    Trace.WriteLine(DateTime.Now + " - Slept for 1 second...");
}

線程使用WritingThread() 方法來睡眠一秒然后寫一些跟蹤消息。

這里我們創建了一個新的FileStream 對象,如果文件存在則打開否則新建一個。然后,我們在Add()方法中創建一個TextWriterTraceListener 類的新的實例並將其添加到監聽器集合中:

FileStream fs = new FileStream(@"C:\Debugging.log", FileMode.OpenOrCreate);
Trace.Listeners.Add(new TextWriterTraceListener(fs));

啟動線程以后,代碼等待用戶輸入回車鍵然后關閉監聽器程序並將所有跟蹤信息寫入到日志文件中:

Trace.WriteLine(DateTime.Now + "- Entered Main()");

Thread t = new Thread(new ThreadStart(WritingThread));
t.Start();

Console.ReadLine();
Trace.Close();

代碼的輸出結果如下:

2012/4/24 22:22:35- Entered Main()
2012/4/24 22:22:35- Entered WritingThread()
2012/4/24 22:22:36- Slept for 1 second...

Trace 類提供了一個有用的屬性IndentLevel 來縮進跟蹤消息。例如,你可以在主次線程中使用不同的縮進級別寫跟蹤消息。在上面代碼中添加如下一行代碼,我們就可以輕松地實現這個功能:

private static void WritingThread()
{
    //Setting indent level
    Trace.IndentLevel = 2;
    Trace.WriteLine(DateTime.Now + "- Entered WritingThread()");
    Thread.Sleep(1000);
    Trace.WriteLine(DateTime.Now + "- Slept for 1 second...");
}

修改后的代碼輸出結果如下:

2012/4/24 22:22:35- Entered Main()
        2012/4/24 22:22:35- Entered WritingThread()
        2012/4/24 22:22:36- Slept for 1 second...

你也可以使用Indent() 和 Unindent() 方法來對應的增加或者減少縮進等級。

 

下一篇介紹跟蹤開關…


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM