---------- using System; using System.Diagnostics; class Test { static void Main() { Trace.Listeners.Add(new TextWriterTraceListener("yourlog.log")); Trace.AutoFlush = true; Trace.Indent(); Trace.WriteLine("Entering Main"); Console.WriteLine("Hello World."); Trace.WriteLine("Exiting Main"); Trace.Unindent(); Trace.Flush(); #if DEBUG string sFile = CCommon.mProject.PathLog + @"\aaa2bbbccc.txt"; TextWriterTraceListener t1 = new TextWriterTraceListener(sFile); Trace.Listeners.Clear(); Trace.Listeners.Add(t1); Trace.WriteLine("hello dynamic trace file from ZRoot()."); Trace.Flush(); #endif } } ---------- ---------- // set up listener string filename = @"C:\listener.txt"; FileStream traceLog = new FileStream( filename, FileMode.OpenOrCreate ); TextWriterTraceListener listener = new TextWriterTraceListener( traceLog ); // output to listener listener.WriteLine( "Trace message here" ); // flush any open output before termination // maybe in an override of Form.OnClosed listener.Flush(); ---------- 先在[App].config 或 Web.config設定 TraceSwitch: 程式寫法如下 private static TraceSwitch appSwitch = new TraceSwitch("mySwitch", "Switch in config file"); public static void Main(string[] args) { //... Console.WriteLine("Trace switch {0} configured as {1}", appSwitch.DisplayName, appSwitch.Level.ToString()); if (appSwitch.TraceError) { //... } } 注意: 在關閉追蹤時,寫法1的執行速度會比較快,因為當 mySwitch.TraceError 評估為 false,就不需呼叫 Write。 寫法2一定會呼叫 WriteIf,即使 mySwitch.TraceError 為 false 且沒有產生任何追蹤輸出。 這會造成不必要的程式碼的執行。 寫法1 if(mySwitch.TraceError) Debug.Write("aNumber = " + aNumber + " out of range"); 寫法2 Debug.WriteIf(mySwitch.TraceError, "aNumber = " + aNumber + " out of range"); 多段Trace/debug if(mySwitch.TraceError) { Debug.Write("aNumber = " + aNumber + " out of range"); Debug.Write("bNumber = " + bNumber + " out of range"); Debug.Write("cNumber = " + cNumber + " out of range"); } ---------- 京奇電腦 ZTrace已整合了.NET Trace/Debug架構. Debug物件與Trace物件原理相同. 若須Debug版本的功能, 請直接呼叫.NET.Debug物件, 才符合系統架構, 不會於正式版本釋出時, 還包含多餘的程式碼. if (ZTrace.g3Info) { Trace.WriteLine("Program P001 Trace log:"); Trace.WriteLine(DateTime.Now); } ZTrace.gTrace1Enabled("Trace.Enabled"); ZTrace.gTrace1Error("TraceError 1"); ZTrace.gTrace2Warning("TraceWarning 2"); ZTrace.gTrace3Info("TraceInformation 3"); ZTrace.gTrace4Verbose("TraceVobose 4"); // 不建議這樣的寫法 ZTrace.gTrace3Info(string.Format("{0}={1}", "Var", "Value")); // 請改成 if (ZTrace.g3Info) Trace.WriteLine(string.Format("{0}={1}", "Var", "Value")); if (ZTrace.g1Enabled) { Trace.WriteLine(ZTrace.gBooleanSwitch.DisplayName); Trace.WriteLine(ZTrace.gBooleanSwitch.Description); } if (ZTrace.g3Info) { Trace.WriteLine(ZTrace.gTraceSwitch.DisplayName); Trace.WriteLine(ZTrace.gTraceSwitch.Description); } ---------- using System; // add using System.IO; using System.Diagnostics; namespace FileLock11 { /// /// Class1 的摘要描述。 /// class PMain { private static DateTime mdStartTime; private static P0010 mP0010; /// /// 應用程式的主進入點。 /// [STAThread] static void Main(string[] args) { // // TODO: 在此加入啟動應用程式的程式碼 // string s1; mdStartTime = DateTime.Now; //s1 = string.Format(@"{0}Trace-FileLock11-{1}.txt", Path.GetTempPath(), mdStartTime.ToString("yyyyMMdd-HHmmss")); s1 = string.Format(@"{0}Trace-{1}.txt", Path.GetTempPath(), mdStartTime.ToString("ss")); // 檔案存在時會append. if (File.Exists(s1)) File.Delete(s1); // output to Console.Out or File // Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); Trace.Listeners.Add(new TextWriterTraceListener(s1)); Trace.AutoFlush = true; Trace.WriteLine(string.Format("{0} BEGIN,{1}", DateTime.Now.ToString("HH:mm:ss"), mdStartTime.ToString("yyyy.MM.dd"))); mP0010 = new P0010(); mP0010.DoLock(); Trace.WriteLine(string.Format("{0} END", DateTime.Now.ToString("HH:mm:ss"))); } } } 若要使用 Trace 和 Debug 類別,請執行下列三個步驟。 定義 TRACE 或 DEBUG 符號。 為對應的 Listener 建立新的執行個體。 為程式碼的 Trace 或 Debug 類別,加入呼叫。 定義 - 您必須先定義對應符號,才能啟用偵錯或追蹤。您可以在編譯時,使用 Visual C# (以及 Managed Extensions for C++) 或 Visual Basic .NET 的 /d(efine) 條件式編譯參數,請參閱下面: csc /target:library /debug+ /d:TRACE math.cs vbc /target:library /debug+ /d:TRACE=True math.vb 原始程式碼本身也可以定義符號,請參閱下面: #define TRACE // for C# or the Managed Extensions for C++ #Const TRACE=1 ' for Visual Basic .NET 建立 - TraceListener可以擷取 Debug 和 Trace 輸出。就預設值而言,輸出會自動傳送到 DefaultTraceListener,再由它使用 OutputDebugString Windows API 將輸出傳送到 Windows 系統偵錯工具,以及使用 Debugger.Log 方法傳送到偵錯工具。如果沒有附加偵錯工具,Debugger.Log 傳送的訊息無效。 果您在 Windows 架構偵錯工具中作業,[輸出] 視窗會顯示 Debug 和 Trace 訊息。不過,如果您在偵錯工具外作業 - 例如,在測試的電腦上 - 或是想將偵錯資訊存入文字架構記錄檔中,您必須建立新的 Listener ,並且加入到 Listeners 集合中。System.Diagnostic 命名空間提供 EventLogTraceListener 和 TextWriterTraceListener。若要建立文字檔來處理偵錯訊息,您只需要下列一行程式碼。 Trace.Listeners.Add(new TextWriterTraceListener(File.Create("output.txt"))); 加入 - 最後,您可以加入各種 Trace.Write 方法呼叫,在 Run Time 時產生偵錯顯示,請參閱下面: Trace.WriteLine(""); Trace.WriteLine("Starting tracing..."); 輸出檔的前幾個位元組中有無法讀取的有關這個檔案的文字編碼資訊,您也許想先執行空的 WriteLine 方法,從新行開始記錄。 另一個值得注意的是呼叫 Trace.Indent,就預設值而言,它會用四個空格來縮排輸出: Trace.Indent(); 後續呼叫 Trace.Unindent,可以向左調整輸出。 某個條件不符時,這個範例程式會使用 Trace 的 WriteLineIf 方法,產生記錄訊息。在此特殊狀況下,程式碼預期第一個數值項目是以非零的數字開頭。如果測試失敗,則會寫下一則訊息,請參閱下行。 Trace.WriteLineIf(test == "0", "Oops: Leading zero"); // C# Trace.WriteLineIf(test = "0", "Oops: Leading zero") ' VB 將這些全部集合起來,執行範例程式,會建立下列的 Output.txt 檔案。 Starting Tracing... InitializeComponent() Creating controls Setting up Label and TextBox Setting up numeric buttons Setting up operations buttons Adding Clear and Calculate Adding to Controls collection 9 Clicked - Clicked 6 Clicked Calculate Clicked Dispose() Assert 方法的操作方式類似,除了它輸出的是詳細的錯誤對話方塊,而且測試失敗。對應的 Assert 方法,類似下列程式碼。 Trace.Assert(test != "0", "Oops", "Leading zero"); // C# Trace.Assert(test <> "0", "Oops", "Leading zero") ' Visual Basic .NET