Visual C Sharp 中的追蹤和偵錯

本文說明如何在 Visual C# 中進行追蹤和偵錯,並提供一些範例步驟來說明相關信息。

原始產品版本: Visual C#
原始 KB 編號: 815788

摘要

如需本文的 Microsoft Visual Basic .NET 版本,請 參閱在 Visual Basic .NET 中使用追蹤和偵錯類別

本文指的是 .NET Framework 類別庫命名空間系統。 診斷並描述如何使用 DebugTrace 類別。 這些類別可在 .NET Framework 中使用。 您可以使用這些類別,在應用程式開發期間或部署至生產環境之後,提供應用程式效能的相關信息。 這些類別只是 .NET Framework 中可用之檢測功能的一部分。

需求

下列清單概述您需要的建議硬體、軟體、網路基礎結構和 Service Pack:

  • Microsoft Windows
  • Microsoft Visual C#

本文也假設您已熟悉程序偵錯。

技術描述

使用 偵錯類別建立範例一 節中的步驟示範如何建立控制台應用程式,以使用 Debug 類別來提供程式執行的相關信息。

當程式執行時,您可以使用 類別的方法 Debug 來產生訊息,以協助您監視程序執行順序、偵測故障,或提供效能測量資訊。 根據預設,類別產生的訊息 Debug 會出現在 Visual Studio 集成開發環境 (IDE) 的 [輸出] 視窗中。

範例程式代碼會使用 WriteLine 方法來產生後面接著行終止符的訊息。 當您使用這個方法來產生訊息時,每個訊息都會出現在 [輸出] 視窗的個別行上。

當您使用 Assert 類別的 Debug 方法時,只有在指定的條件評估為 false 時,[輸出] 視窗才會顯示訊息。 訊息也會出現在使用者的模式對話框中。 對話框包含訊息、項目名稱和 Debug。 Assert 語句編號。 對話框也包含下列三個命令按鈕:

  • 中止: 應用程式會停止執行。

  • 重試: 應用程式進入偵錯模式。

  • 忽略: 應用程式會繼續進行。 用戶必須按兩下其中一個按鈕,應用程式才能繼續。

您也可以將輸出從 Debug 類別導向至 [輸出] 視窗以外的目的地。 類別 Debug 具有包含 Listener 物件的 Listeners 集合。

每個接聽程式物件都會 Debug 監視輸出,並將輸出導向至指定的目標。

接聽程式集合中的每個接聽程式都會收到類別產生的任何輸出 Debug 。 使用類別 TextWriterTraceListener 來定義 Listener 物件。 您可以透過類別的建構函式來 TextWriterTraceListener 指定類別的目標。

一些可能的輸出目標包括:

  • 使用屬性的 System.Console.Out 主控台視窗。
  • 使用語句 (.txt) 檔案的 System.IO.File.CreateText("FileName.txt") 文字。 建立 TextWriterTraceListener 物件之後,您必須將 物件新增至 Debug。 要接收 Debug 輸出的接聽程式集合。

使用偵錯類別建立範例

  1. 啟動 Visual Studio 或 Visual C# Express Edition。

  2. 建立名為 conInfo 的新 Visual C# 控制台應用程式專案。 Class1 是在 Visual Studio .NET 中建立。 Program.cs會在Visual Studio 2005中建立。

  3. 在 Class1 或 Program.cs 的頂端新增下列命名空間。

    using System.Diagnostics;
    
  4. 若要初始化變數以包含產品的相關信息,請將下列宣告語句新增至Main方法:

    string sProdName = "Widget";
    int iUnitQty = 100;
    double dUnitCost = 1.03;
    
  5. 指定 類別產生的訊息,做為 方法的第一個輸入參數 WriteLine 。 按 CTRL+ALT+O 按鍵組合,以確定 [輸出] 視窗是可見的。

    Debug.WriteLine("Debug Information-Product Starting ");
    
  6. 為了方便閱讀,請使用 Indent 方法在 [輸出] 視窗中縮排後續訊息:

    Debug.Indent();
    
  7. 若要顯示所選變數的內容,請使用 方法, WriteLine 如下所示:

    Debug.WriteLine("The product name is " + sProdName);
    Debug.WriteLine("The available units on hand are" + iUnitQty.ToString());
    Debug.WriteLine("The per unit cost is " + dUnitCost.ToString());
    
  8. 您也可以使用 WriteLine 方法來顯示存在物件的命名空間和類別名稱。 例如,下列程式代碼會在 [輸出] 視窗中顯示 System.Xml.XmlDocument 命名空間:

    System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
    Debug.WriteLine(oxml);
    
  9. 若要組織輸出,您可以將類別納入為方法的選擇性第二個輸入參數 WriteLine 。 如果您指定類別,[輸出] 視窗訊息的格式會是 “category: message”。例如,下列程序代碼的第一行會在 [輸出] 視窗中顯示 “Field: The product name is Widget”:

    Debug.WriteLine("The product name is " + sProdName,"Field");
    Debug.WriteLine("The units on hand are" + iUnitQty,"Field");
    Debug.WriteLine("The per unit cost is" + dUnitCost.ToString(),"Field");
    Debug.WriteLine("Total Cost is " + (iUnitQty * dUnitCost),"Calc");
    
  10. 只有當指定的條件使用 類別的 方法Debug評估為 true 時,WriteLineIf[輸出] 視窗才能顯示訊息。 要評估的條件是 方法的第一個輸入參數 WriteLineIf 。 的第二個參數是只有在第一個參數 WriteLineIf 中的條件評估為 true 時才會出現的訊息。

    Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
    Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");
    
  11. 使用 類別的 Debug Assert 方法,以便只有在指定的條件評估為 false 時,[輸出] 視窗才會顯示訊息:

    Debug.Assert(dUnitCost > 1, "Message will NOT appear");
    Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");
    
  12. TextWriterTraceListener建立主控台視窗 (tr1) 和名為 Output.txt( tr2) 的文字檔的物件,然後將每個物件新增至偵錯接聽程式集合:

    TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
    Debug.Listeners.Add(tr1);
    
    TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt"));
    Debug.Listeners.Add(tr2);
    
  13. 為了方便閱讀,請使用 Unindent 方法來移除 類別所產生之後續訊息的 Debug 縮排。 當您同時使用 IndentUnindent 方法時,讀取器可以將輸出區分為群組。

    Debug.Unindent();
    Debug.WriteLine("Debug Information-Product Ending");
    
  14. 若要確定每個物件都會 Listener 接收其所有輸出,請呼叫類別緩衝區的 Flush 方法 Debug

    Debug.Flush();
    

使用追蹤類別

您也可以使用 Trace 類別來產生監視應用程式執行的訊息。 和 TraceDebug 類別會共用大部分相同的方法來產生輸出,包括下列各項:

  • WriteLine
  • WriteLineIf
  • 縮排
  • Unindent
  • 斷言
  • 沖洗

您可以在 Trace 相同的應用程式中個別或一起使用和 Debug 類別。 在偵錯方案組態專案中,和 Debug 輸出都是Trace作用中。 專案會從這兩個類別產生所有 Listener 對象的輸出。 不過,發行方案組態專案只會從 Trace 類別產生輸出。 發行方案組態專案會忽略任何 Debug 類別方法調用。

Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();

Trace.WriteLine("The product name is "+sProdName);
Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");

Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");

Trace.Flush();

Console.ReadLine();

確認其運作正常

  1. 請確定 [偵錯] 是目前的解決方案組態。

  2. 如果看不到 方案總管 視窗,請按 CTRL+ALT+L 按鍵組合以顯示此視窗。

  3. 以滑鼠右鍵按兩下 conInfo,然後按兩下 [ 屬性]

  4. conInfo 屬性頁的左窗格中,於 [組態 ] 資料夾 底下,確定箭號指向 [ 偵錯]

    注意事項

    在 Visual C# 2005 和 Visual C# 2005 Express Edition 中,按兩下 conInfo 頁面中的 [錯]。

  5. 在 [組態] 資料夾的 [組態] 下拉式清單框中,按兩下 [作用中 (偵錯]) 或 [偵錯],然後按兩下 [確定]。 在 Visual C# 2005 和 Visual C# 2005 Express Edition 中,單擊 [偵錯] 頁面的 [組態] 下拉式清單框中的 [作用 (偵錯) ] 或 [偵錯],然後按兩下 [檔案] 選單上的 [儲存]。

  6. CTRL+ALT+O 以顯示 [輸出] 視窗。

  7. F5 鍵以執行程式碼。 當 [ 判斷提示失敗 ] 對話框出現時,按兩下 [ 忽略]

  8. 在 [ 控制台] 視窗中,按 ENTER。 程式應該會完成,而 [ 輸出 ] 視窗應該會顯示類似下列的輸出:

    Debug Information-Product Starting
    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    System.Xml.XmlDocument
    Field: The product name is Widget
    Field: The units on hand are100
    Field: The per unit cost is1.03
    Calc: Total Cost is 103
    This message WILL appear
    ---- DEBUG ASSERTION FAILED ----
    ---- Assert Short Message ----
    Message will appear since dUnitcost < 1 is false
    ---- Assert Long Message ----
    
    at Class1.Main(String[] args) <%Path%>\class1.cs(34)
    
    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name isWidget
    This message WILL appear
    Trace Information-Product Ending
    
  9. 主控台視窗和 Output.txt 檔案應該會顯示下列輸出:

    The product name is Widget
    The available units on hand are 100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name is Widget
    This message WILL appear
    Trace Information-Product Ending
    

注意事項

Output.txt 檔案位於與 conInfo 可執行檔 (conInfo.exe) 相同的目錄中。 一般而言,這是儲存專案來源的 \bin 資料夾。 根據預設,這是 C:\Documents and Settings\User login\My Documents\Visual Studio Projects\conInfo\bin。 在 Visual C# 2005 和 Visual C# 2005 Express Edition 中, Output.txt 檔案位於 資料夾中: C:\Documents and Settings\User login\My Documents\Visual Studio 2005\Projects\conInfo\conInfo\bin\Debug

完整程式代碼清單

using System;
using System.Diagnostics;

class Class1
{
    [STAThread]
    static void Main(string[] args)
    {
        string sProdName = "Widget";
        int iUnitQty = 100;
        double dUnitCost = 1.03;
        Debug.WriteLine("Debug Information-Product Starting ");
        Debug.Indent();
        Debug.WriteLine("The product name is "+sProdName);
        Debug.WriteLine("The available units on hand are"+iUnitQty.ToString());
        Debug.WriteLine("The per unit cost is "+ dUnitCost.ToString());

        System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
        Debug.WriteLine(oxml);

        Debug.WriteLine("The product name is "+sProdName,"Field");
        Debug.WriteLine("The units on hand are"+iUnitQty,"Field");
        Debug.WriteLine("The per unit cost is"+dUnitCost.ToString(),"Field");
        Debug.WriteLine("Total Cost is "+(iUnitQty * dUnitCost),"Calc");

        Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
        Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");

        Debug.Assert(dUnitCost > 1, "Message will NOT appear");
        Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");

        TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
        Debug.Listeners.Add(tr1);

        TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt"));
        Debug.Listeners.Add(tr2);

        Debug.WriteLine("The product name is "+sProdName);
        Debug.WriteLine("The available units on hand are"+iUnitQty);
        Debug.WriteLine("The per unit cost is "+dUnitCost);
        Debug.Unindent();
        Debug.WriteLine("Debug Information-Product Ending");
        Debug.Flush();

        Trace.WriteLine("Trace Information-Product Starting ");
        Trace.Indent();

        Trace.WriteLine("The product name is "+sProdName);
        Trace.WriteLine("The product name is"+sProdName,"Field" );
        Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
        Trace.Assert(dUnitCost > 1, "Message will NOT appear");

        Trace.Unindent();
        Trace.WriteLine("Trace Information-Product Ending");

        Trace.Flush();

        Console.ReadLine();
    }
}

疑難排解

  • 如果方案組態類型為 Release,則 Debug 會忽略類別輸出。

  • 在您建立 TextWriterTraceListener 特定目標的類別之後,接收 TextWriterTraceListener 來自 Trace 和類別的 Debug 輸出。 不論您是使用 Add 或 類別的 Trace 方法來加入TextWriterTraceListenerListeners至 類別,Debug都會發生這種情況。

  • 如果您在和 Debug 類別中新增Listeners相同目標的 Trace 物件,則不論 是或DebugTrace產生輸出,每一行輸出都會重複。

    TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
    Debug.Listeners.Add(myWriter);
    
    TextWriterTraceListener myCreator = new TextWriterTraceListener(System.Console.Out);
    Trace.Listeners.Add(myCreator);
    

參考資料