共用方式為


Visual C 中的追蹤和偵錯

本文說明如何在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 主控台視窗。
  • 使用 System.IO.File.CreateText("FileName.txt") 語句的文字 (.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”。例如,下列程序代碼的第一行會在 [輸出] 視窗中顯示 「字段:產品名稱為 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. 只有在指定的條件使用 WriteLineIf 類別的 Debug 方法評估為 true 時,[輸出] 視窗才會顯示訊息。 要評估的條件是 方法的第一個輸入參數 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) 的文字檔,然後將每個物件新增至 Debug Listeners 集合:

    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 物件都接收其所有輸出,請針對 Debug 類別緩衝區呼叫 Flush 方法:

    Debug.Flush();
    

使用追蹤類別

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

  • WriteLine
  • WriteLineIf
  • 訂貨單
  • Unindent
  • Assert
  • 清除

您可以在相同的應用程式中個別或 Trace 一起使用和 Debug 類別。 在偵錯方案組態專案中, TraceDebug 輸出都處於作用中狀態。 專案會從這兩個類別產生輸出到所有 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接收和類別的Debug輸出Trace。 不論您使用 Add 的方法 TraceDebug 類別來新增 TextWriterTraceListenerListeners 類別,都會發生此情況。

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

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

參考資料