當你的程序接近部署階段時,你可能想從代碼中去掉所有的跟蹤和調試消息。然而,你不得不從代碼中一條一條地尋找調試指令並將其去掉。對於這種情況你可以在程序編譯期間使用編譯標志處理。從Visual Studio.NET IDE, 你可以在解決方案管理窗口右鍵工程名->從菜單頁選擇屬性。如下圖對話框顯示:
你只需要簡單地將定義調試常量和跟蹤常量選項勾掉,重新編譯解決方案,所有的跟蹤和調試代碼都將會被從應用程序中被去掉。
為了去掉跟蹤功能,你可以使用csc.exe 命令行編譯器。在編譯時使用/d:TRACE=FALSE /d:DEBUG=FALSE 開關。
對跟蹤代碼添加開關功能允許我們在運行時激活/反激活跟蹤消息。通過簡單地在我們程序的配置文件中定義一個值,你就可以激活跟蹤功能而不用重新編譯代碼。通常情況下,為了維持跟蹤信息你需要將其集成到應用程序中,結果就是程序變得越來越大、越來越慢,即便跟蹤開關已經被關閉。
BooleanSwitch 和 TraceSwitch 類是.NET Framework 提供來是實現這些開關的。讓我們先來看看BooleanSwitch 類。
BooleanSwitch 類
在跟蹤代碼中使用這個類,你可以通過簡單地改一下配置文件來激活/反激活消息。WriteLineIf() 和 WriteIf() 方法根據BooleanSwitch 類的Enabled 屬性決定是否寫消息。為了在你的程序中添加開關你需要按以下步驟執行:
1. 手動添加一個配置文件或者通過在項目菜單添加一個新文件來添加App.config 文件。
2. 打開配置文件添加如下信息。0 表示禁用跟蹤功能,1 表示激活跟蹤功能。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <switches> <add name="MySwitch" value ="1"/> </switches> </system.diagnostics> </configuration>
3. 在代碼中創建一個新的BooleanSwitch 對象並設置其名字與配置文件中的一樣。在下面的代碼中我們定義一個全局BooleanSwitch對象:
static BooleanSwitch bs; static void Main(string[] args) { //Create a Boolean switch called MySwitch bs = new BooleanSwitch("MySwitch", "Enable/Disable tracing functionalites"); //Create a file listener FileStream fs = new FileStream(@"D:\Debugging.log", FileMode.OpenOrCreate); Trace.Listeners.Add(new TextWriterTraceListener(fs)); //Write the line only when the switch is on Trace.WriteLineIf(bs.Enabled, DateTime.Now + "- Entered in Main()"); }
在Main() 方法中我們創建了對象,並使用與配置文件中相同的名字對其初始化。WriteLineIf() 方法僅當配置文件中的Enabled 設置為1 時才寫消息。
TraceSwitch 類
這個類是BooleanSwitch 類的高級版本因為它允許我們選擇是否反激活跟蹤功能或者按照不同重要層次來顯示信息。下表列出了不同等級:
所以,當發生了一個錯誤時,你可以改變應用程序配置文件,來設定只向監聽程序寫入你加到代碼中的錯誤信息,這樣可以僅關注這些信息。配置文件的設置與BooleanSwitch 例子相同。代碼中的改變是我們需要從TraceSwitch 類來實例化一個對象。還有我們將在類中使用枚舉來確定跟蹤消息的層次。現在來看一個例子,TraceSwitchExample.cs:
static TraceSwitch ts; [STAThread] static void Main(string[] args) { //Create a BooleTraceSwitchan switch called MySwitch ts = new TraceSwitch("MySwitch", "Four different trace levels"); //Create a file listener FileStream fs = new FileStream(@"D:\Debugging.log", FileMode.OpenOrCreate); Trace.Listeners.Add(new TextWriterTraceListener(fs)); //Write the line only when the switch is on Trace.WriteLineIf(ts.TraceInfo, DateTime.Now + "- Entered in Main()");; //Create a thread Thread t = new Thread(new ThreadStart(DBThread)); t.Start(); Console.ReadLine(); Trace.Close(); }
我們定義了一個全局TraceSwitch 對象然后通過配置文件中的名字生成一個新的實例。我們添加一個文本監聽器到程序中。然后啟動一個新線程來連接數據庫獲得Region 表中的所有信息。
如果線程已經啟動而且Open() 方法產生一個異常時將會產生一條錯誤消息:
private static void DBThread() { Trace.WriteLineIf(ts.TraceInfo, DateTime.Now + "- Entered in DBThread()"); //Create a connection object SqlConnection dbConn = new SqlConnection(@"Data Source=DANIELFORWARD\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"); //Create a command object to execute a SQL statement SqlCommand dbComm = new SqlCommand("SELECT * FROM Region", dbConn); SqlDataReader dr = null; try { Trace.WriteLineIf(ts.TraceInfo, DateTime.Now + "- Execute SQL statement"); //Open the connection to the database dbConn.Open(); //Execute the SQL statement dr = dbComm.ExecuteReader(System.Data.CommandBehavior.CloseConnection); while (dr.Read()) { //Reading records Trace.WriteLine(dr[0].ToString()); } } catch (Exception ex) { //Log the error to the Trace application Trace.WriteLineIf(ts.TraceError, DateTime.Now + " An error occured in database access, details: " + ex.Message); } finally { if (!dr.IsClosed && dr != null) { dr.Close(); } } }
當在配置文件中設定值為1時,TraceError 信息的輸出結果如下:
2012/4/25 21:35:29 An error occured in database access, details: 在與 SQL Server 建立連接時出現與網絡相關的或特定於實例的錯誤。
未找到或無法訪問服務器。請驗證實例名稱是否正確並且 SQL Server 已配置為允許遠程連接。 (provider: SQL 網絡接口, error: 26 - 定位指定的服務器/實例時出錯)
當配置文件中設定值為3時,TraceInformation 信息的輸出結果如下:
2012/4/25 21:37:10- Entered in Main()
2012/4/25 21:37:12- Entered in DBThread()
2012/4/25 21:37:12- Execute SQL statement
2012/4/25 21:37:27 An error occured in database access, details: 在與 SQL Server 建立連接時出現與網絡相關的或特定於實例的錯誤。
未找到或無法訪問服務器。請驗證實例名稱是否正確並且 SQL Server 已配置為允許遠程連接。 (provider: SQL 網絡接口, error: 26 - 定位指定的服務器/實例時出錯)
Debug 類
Debug 類提供與Trace 類同樣的功能。當你改變Trace 類提供的監聽器集合中的監聽器程序時,你可以在Debug 類中做同樣的事情。
這兩個類最大的不同在於應用的不同場景。Debug 類用於調試階段添加信息。在部署我們的應用程序之前,你將創建一個發布版本同時自動去除所有調試信息。因此,你可以在程序運行階段需要的時候添加Trace 類功能。
下一篇介紹一個DataImport 的例子…