Edit and Contiue功能
在調試程序的時候,經常會遇到這樣的情況:在調試一大段代碼時,遇到了一個小的錯誤,比如參數的賦值錯誤了,這時候,往往希望能夠馬上將這些小的錯誤改正過來後,能夠繼續調試跟蹤下去,而不用結束整個調試過程去修改。在Visual Studio 2003中,我們必須停止當前的調試,修改錯誤的地方,再重新編譯,這樣十分不方便。在Visual Studio 2005 中,提供了一個新的功能叫"edit and continue",意思是說,當你在調試時,遇到小的錯誤需要馬上修改後,可以進行編輯修改,然後繼續往下調試,不需要結束整個調試的過程,當你修改後,調試器在後台進行了自動的編譯,並且會執行新修改的代碼,十分方便。下面舉個例子進行說明。
打開Visual Studio 2005,使用c#建立一個winform窗體應用程序,在窗體中添加一個label標簽,一個文本框,一個按鈕,如下圖所示,我們要實現的功能是,在文本框輸入一些信息後,點按鈕,會彈出一個消息框,顯示的是剛才輸入的信息。
假如我們編寫的代碼如下所示,出現了一個小錯誤,把textbox1.text的內容當作字符串的一部分了,所以顯示不出用戶輸入的信息。
private void button1_Click(object sender, EventArgs e)
{
//Show welcome message
MessageBox.Show("Welcome textbox1.Text to Edit and Continue.");
}
現在,如果我們在調試時遇到了這個錯誤,則可以使用edit and continue功能來進行改正。
首先,按F7切換到代碼視圖,在MessageBox.Show這一行設置斷點,之後按F5運行程序,當在文本框輸入字符串時,由於設置了中斷,光標停留在messagebox.show這行上,這時,我們可以修改代碼,修改為:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Welcome " + textbox1.Text +" to Edit and Continue.");
}
修改完後,繼續按F5運行,這時候,則會顯示正確的結果了,如下圖,而不需要使用以往的"stop debugging"的功能先停止調試再修改程序。
可視化調試器(Debugging Visualizers)
在調試的時候,我們遇到的一個很麻煩的問題,就是有的時候很難看到某些參數的值。比如當你設置了一個斷點去監測一個dataset,並且想看dataset裡的每個datatable的數據,這在Visual Studio 2003中,是十分麻煩的,必須在auto/locals的監視窗口中,一層層地展開去看其值。在Visual Studio 2005中,為解決這個問題,新增加了叫"debugging visualizers"(可視化調試器)的功能,該功能可以在調試狀態時,很容易方便地以各類形式,比如文本,html,xml等方式查看各種參數。
在各類的監視窗口中,比如在autos,locals,watch和quickwatch 中都可以調用可視化調試器,方法是在某個需要監視的參數旁邊,點擊那個放大鏡圖標,就可以在打開的可視化調試器中看到該參數的詳細情況,如下圖所示:
利用可視化調試器,就可以很方便地查看比如dataset類型的數據,如下圖所示:
Data Tips
在Visual Studio 2005中,在調試方面,還新增了"data tips(數據提示)"的功能。當在調試程序期間,只需要將光標移到代碼中某個需要監視的參數上,系統就會自動顯示與該參數相關聯的一些很有用的信息,比如相關的屬性,以及當前該參數的值。在Visual Studio 2003中,也有該功能,但提供的信息比現在的2005少很多。
我們依然以上面"edit and continue"使用的例子來說明。我們將斷點設在MessageBox.Show這一行,F5運行程序,當在文本框輸入文字並按確定按鈕後,程序自動中斷,這時,將光標移到textbox1.text這個位置,系統就會調用data tips功能,如下圖所示顯示出與textbox文本框控件相關的一些屬性以及這些屬性此時對應的值。
在data tip的功能中,還可以繼續使用edit and continue的功能,只需要在需要的地方鼠標右鍵就可以彈出如下圖的菜單,可以編輯該值。
Exception Assistant(異常助手)
在Visual Studio .net 2003中,當程序運行出現異常時,系統會顯示一個異常信息對話框,詢問是否停止程序執行或繼續運行程序,但並沒有提供給開發者更多的關於異常的信息。在Visual Studio .net 2005中,提供了 Exception Assistant(異常助手)的新功能,可以顯示豐富的關於異常方面的信息,幫助開發者調試,如下圖:
在上圖中,顯示的是一個sqlException,是由於超時連接而造成的。在異常助手的窗口中,顯示了關於該異常的詳細信息,還可以將這些信息復制到剪貼版中,當選擇view detail時,會彈出如下圖所示的窗口,進一步顯示關於該異常的詳細信息:
Just My Code Debugging
在調試代碼中,我們經常會遇到這樣的問題,有時我們引用了一些其他工具包或者類庫(如Microsoft提供的Enterprise Library),而在調試時,我們其實是不需要跟蹤調試這些代碼的,因為它們都已經證明是正確的。在Visual Studio 2003中,處理這類問題我們的方法一般是使用F10跳過它們,但一旦工程龐大的話,這樣做十分麻煩。在Visual Studio 2005中,新增加了Just My Code debugging(JMC)的新特性,可以讓開發者自己定制哪些代碼是需要調試,哪些代碼是永遠不需要調試的,這樣可以節省大量的時間。
JMC功能由兩方面來實現。首先,如果一個工程是以release方式進行編譯構建的話(就是工程中,沒有pdb文件),調試器會將其認為是非用戶代碼,那麼在調試運行時,就根本不會進入該工程中進行調試。其次,可以使用System.Diagnostics命名空間裡的DebuggerNonUserCodeAttribute屬性,將其應用在希望不進行調試的代碼段中。
下面舉一個例子來說明。下面的代碼段中,有兩個靜態方法UserCode()和NonUserCode(),其中,在NonUserCode()中,是應用了DebuggerNonUserCode的屬性,這表明這段代碼將在調試運行時,調試器不會進入其中。將斷點設置在其中的第9行,運行程序,程序會在第一個UserCode()裡中斷,現在試著用F11繼續單步跟蹤,會發現系統在進入usercode()方法中運行後,並沒有進入到NonUserCode()裡運行。
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
// Step into F11 from here
UserCode();// Place break point on this line
NonUserCode();
UserCode();
}
static void UserCode()
{
Console.WriteLine("This is a call from user Code");
}
// Attribute to indicate the Debugger to jump
// over this method
[DebuggerNonUserCode]
static void NonUserCode()
{
Console.WriteLine("This is a call fron Non User Code");
}
}
編輯時對象識別
在Visual Studio 2005中,新引入了"Object Identity While Debugging"的概念,也就是說,系統給在調試階段的每個對象,都可以賦予一個別名,在調試時,直接引用該別名就可以了。
假設在調試的時候,需要跟蹤比如dataset或者hashtable等對象,這些對象中包含了很多其他的子對象,如果想對這些數量眾多的子對象進行跟蹤的話,將十分麻煩。在Visual Studio 2005中,可以使用object identity(對象標識)的方法去標記每一個對象,
比如,在一個windows應用程序中,創建了一個dataset,並將其綁定到datagridview中去。如將sql server 的northwind數據庫中的orders和orderdetail表中的數據讀出填充到dataset裡去,則在調試時,設置一個斷點放在dataset裡填充了數據之後的那行,這時,在監視窗口中,鼠標展開this.northwindData這個dataset,如下圖所示,找到orders這個table,然後鼠標右鍵,會彈出一個菜單,選擇其中的" Make Object ID".
這時,會將orders這個參數以1#的別名方式命名(見下圖),並且在整個應用程序中,只要在dataset的生存期,都可以以1#的方式訪問它。
下圖的代碼演示了如何在immediate監視窗口中,通過使用object 標識,查看某一個表中所有記錄的方法。要注意的是,必須將其顯式類型轉換為DataApp.NorthwidDataSet.OrdersDataTable。通過使用object 標識的好處是,可以在調試階段,不需要在描述某個參數時,再用冗余的命名方法表示了(比如可以用#1來代替this.NorthwidDataSet.Orders)