C#調試三部曲:從入門到精通

來源:互聯網
上載者:User

     C#調試,對新手應該有協助,原文地址:http://tech.it168.com/a2010/1116/1126/000001126474_all.shtml

     我們在做程式開發時,難免會遇到錯誤異常。如何快速地找到出錯的地方、分析錯誤的原因以及找到問題的解決方案,是許多初級程式員困擾的問題,這也正是經驗的寶貴之處。下面我將簡單介紹在Visual Studio中調試以及一些進階的調試和常見的錯誤。

  PS:如無特別說明Visual Studio均指Dev10即Visual Studio 2010。

  入門篇

  假設你是有著.Net平台的程式員,並且使用Visual Studio 做為開發工具。

  斷點:最簡單的一種,設定一個斷點,程式執行到那一句就自動中斷進入調試狀態。設定斷點,在你覺得有問題的程式碼,左側單擊,會出現紅色的紅點即斷點。

  啟動調式:按F5,或者功能表列---調式---開始調試,或者工具列的表徵圖

  快速監視:快速查看變數或者運算式的值,也可以自訂運算式進行計算

  逐步執行

  有三種,一種是每次執行一行(F10);一種是每次執行一行,但遇到函數調用就會跳到被調用的函數裡(F11);一種是直接執行當前函數裡剩下的指令,返回上一級函數(Shift+F11)。

  還有一種後悔藥,設為下一句(Set Next Statement),即下一句會被執行的語句(右擊設定或者快速鍵:Ctrl+Shift+F10),但要注意在調試與資料有關的時候,設定下一句有可能會報異常。如在調試向DataTable中添加行的時候,已經存在的行不能重複被添加到DataTable中。

  監視

  調試器可能會自動列出一些相關變數的值,但是你可能還關心其它變數的值,可以添加對這些變數的監視。還可以監視一個運算式的值,比如a+b。但是,這個運算式最好不要修改變數的值,比如監視a++都會導致監視時修改了a的值,影響了程式的運行結果。  

  調試技巧篇

  使用快速鍵會大大提升我們的調試效率,常用的調試快速鍵:

  F5 啟動調試

  F10 執行下一行代碼,但不執行任何函數調用。

  F11 在執行進入函數調用後,逐條語句執行代碼。

  Shift + F11 執行當前執行點所處函數的剩餘行。

  Shift + F5 停止運行程式中的當前應用程式。可用於“中斷”模式和“運行”模式。

  拖動斷點(感謝 聖殿騎士的提醒)

  在調試中,我們可以拖動斷點,使得程式運行到我們想要啟動並執行地方。通常是用來驗證這段代碼對程式的運行結果有沒有影響的。因為我們拖動代碼,則被過濾的代碼就不會執行,將它跟原來的相比,可以看出去掉這段代碼有什麼影響

 條件中斷

  假如你寫了個for迴圈,而且迴圈的次數比較多,如下代碼,現在我們知道在i=50的時候會有異常,那我們不可能按50次F5去調試這代碼,不然這效率….

private void ConditionDebug()
{     
for (int i = 0; i < 100; i++)       {           
if (i==50)         
{       
//some error code here   
Console.WriteLine("i=50 here");         
}      }  }

  我們可以直接利用vs提供的功能修改變數i的值,一開i=0,即剛進入for迴圈中,我們設定將i改為49並斷行符號,再調試一次,會發現i=50; 如

  當然我們也可以直接在代碼裡寫代碼以達到這個目的,代碼如下

private void ConditionDebug() 
{             
for (int i = 0; i < 100; i++)             

System.Diagnostics.Debug.Assert(i != 50);               
if (i==50)               
{         
//some error code here         
Console.WriteLine("i=50 here");               
}              }  }  

  使用了調試中的Assert(斷言),當執行程式後會彈出如下的提示框,點擊Ingore(忽略)即可,

Immediate Window

  Immediate window在調試的時候計算運算式的值、執行語句、列印變數的值等。我們輸入命令(注意一定要以“>”開頭),會有智能提示,而且命名都是自解釋型。

  如,我們現在想要知道i的值,可以輸入命名>Debug.Print i(也可以簡單的使用>? i),如

  Immediate window還有更強大的用法,計算方法的傳回值(如果有的話)

  如果有這個的函數

int MethodValue(int a) 
{           
if (a==1)             
{                 
return 1;         
   }           
else
   {           
      return 0;     
        }  }

  我們可以使用Immediate命令 >? class.Method(args) 去調用這個方法,如

  其中p是當前類的執行個體(因為MethodValue是類的方法,注意?和運算式之間要有空格)

  對於一些即時性很高的程式(如socket)使用 Debug.Write()把錯誤寫到記錄檔中,.Net可以將Debug資訊寫到你指定的檔案中,記住,寫進出的資訊不一定是出錯的資訊,也可以是你的程式的啟動並執行一些重要訊息,當你調試過程中發現某個模組出了問題,但是不能決定位置,那你就可以使用這個方法,如果是一天才出一個錯誤,那你就更要使用這個方法。 

  執行個體篇

 涉及到WS(WebServices)的調試

  在基於WinForm的實際開始開發中,我們往往採用WS用做資料的傳遞,我們在前台擷取收集資料,通過WS將資料傳遞給後台,後台做相應的商務邏輯處理後,會持久到資料庫中。而往往我們又會在WS中寫一些相關的代碼,如身分識別驗證、日誌記錄、提示資訊等,怎樣去調試這些代碼呢。

 涉及到JavaScript的調試

  許多程式員為調試JavaScript感到困惑不已,因為沒有一款很好的調試工具。一些人喜歡使用FireBug來調試JavaScript,確實是一個不錯的選擇,Firebug提供了許多的JavaScript資訊,是一款不錯的調試JavaScript的工具。下面我將會介紹如何使用Visual Studio調試JavaScript,Visual Studio中調試JS跟調試C#差不多,都是設定斷點,不同的是我們在查看元素值的時候需要注意點。

涉及到Ajax的調試

  現在ajax已經十分的流行,但是隨之而來的即調試困難,大部分初級程式員不知道如何有效地從前台調試到後台代碼,以至出了很多不完善的ajax應用。

  下面以一個簡單的執行個體來介紹如何使用Visual Studio調試JavaScript。執行個體是使用Ajax驗證使用者登入,如果驗證通過,則提示“登入成功”,否則提示“登入失敗”。

  下面是主要的代碼,我們使用jQuery來實現ajax,並且在後台檔案中故意出錯。

  正確的使用者名稱和密碼是admin和1

  調試方法如下,在後台入口處設定斷點,然後在前台js中調用背景方法處設定斷點,然後按F5啟動調試,當我們輸入使用者名稱、密碼後,點擊登入後會發現,前台斷點被觸發了。

  按F5繼續調試,有時候會跳到jQuery的源碼中,不管他,繼續F5,會發現執行到後台中的斷點中,如

  而後台代碼的調試是十分簡單的。(PS:有時候無需在前台設定斷點也可直接進入背景調試,如何不行的話,在前台html檔案或者aspx檔案中認為有可能出錯的地方設定斷點,一步步調試)

  一些調試中出現的常見錯誤(會陸續更新):

  1. 我們調試到某一句代碼的時候,突然莫名奇妙的跳出來了,其實是剛剛執行的這一句話有異常,我們可以使用try…catch進行異常捕獲,看看異常原因是什麼,然後做相應的處理

  2. 在ADO.NET,我們會使用ds.Merge()方法進行合并記憶體表,如果有異常的話,一般有以下三種情況

  A.其中一張表中有兩行一模一樣的資料,包括主鍵

  B.這兩張表的結構不一致

  C.兩張表中某個欄位的類型不符,如欄位age在A表中式string,而在B表中確是Decimal

 斷點篇

 叫用次數(Hit Counts)

  右擊斷點,可以設定Hit Counts(叫用次數),會彈出如下的對話方塊

  當條件滿足的時候斷點會被命中(即即將被執行),這個叫用次數是斷點被命中的次數。預設是始終break,選項有如下的幾種:始終break;當叫用次數達到多少次時break;當叫用次數是多少的倍數時break;當叫用次數大於等於多少的時候break。

  於是在上篇中的條件也可以這樣實現,設定叫用次數等於50的時候break,按F5後,斷點被觸發,此時i=50。 

  斷點過濾器

  我們可以限制斷點在特定的處理器和進程中。可以設定機器名、進程id、進程名、線程id、線程名中的某些條件來過濾一些斷點。

  注意:ThreadId需要特別說明一下,ThreadId並不是託管程式中,.NET 架構中System.Threading.Thread.ManagedThreadId,兩者不能等同。簡單來說,ManagedThreadId是線程在CLR中的標識符,而ThreadId卻是線程在作業系統中的標識符。因此ThreadId需要從調試器中的“Threads”視窗中擷取。

斷點條件

  我們可以設定斷點達到的條件,如,我們設定運算式為i==5(注意是判相等,而不是賦值的等於),按F5,斷點再次被觸發,此時i=50。

  還有一個選項是已經被改變,則裡麵條件是具體的變數,如我們的代碼如下

private void ConditionDebug()
{
int hitCount = 0;
for (int i = 0; i < 100; i++)
            {
if (i==49)
                {
                    hitCount = 1;
                }   
            }
            Console.Write("Hit Count={0}", hitCount);
}

  我們在代碼裡如果i==49,就將hitCount的值改變,同時設定斷點的條件為

  則當斷點再次被觸發的時候此時i=50。這個通常被用在找變數的時在什麼時候發生改變。

 斷點的位置

  可以設定斷點的位置,如,設定程式到達那個檔案的第幾行第幾個字元時觸發斷點。

  斷點觸發時…

  我們可以設定斷點到達時做一些其他的事情,如列印訊息,運行一個宏。

  自訂呼叫堆疊

  堆疊追蹤時vs一步步執行你的程式是對當前的方法調用繼承關係的直觀顯示。在偵錯工具時,我們會經過一個又一個方法,包括方法的嵌套調用。堆疊追蹤會對這當中的每一層方法作出記錄。選擇“調試-->視窗-->呼叫堆疊”,或者是快速鍵Ctrl+Alt+C就可以看到當前的堆疊追蹤狀態。這裡會將每個方法單獨顯示為一行,並且帶有行號和參數值。每一個新的方法調用被稱為堆疊框架。

  堆疊追蹤是廣為人知的調試工具,它的優點在於你可以雙擊任意一行跳轉到程式中該層調用方法的代碼。於是你可以看到程式是如何執行到這一位置的,同時可以看到方法接受的參數值。並且可以使用Ctrl+C將一個或者全部堆疊框架複製到剪貼簿,並將這個方法的調用資訊發送給工作夥伴。

   Start external program:調試的時候啟動內部程式

  Start browser with URL:調試的時候開啟URL地址    

使用Trace.axd調試ASP.NET

  在以前asp時候,我們為了查看某個變數的值,通常會使用Response.Write方法。可能現在許多ASP.NET程式員也習慣在後台使用Response.Write方法將變數的值寫出來,其實微軟提供了很好的調試工具,即Trace.axd。它的功能主要是:配置 ASP.NET 代碼Tracing Service以控制如何收集、儲存和顯示跟蹤結果。

  關鍵的幾個選項:

  1、localOnly 預設為false。這個很好理解。如果為true,只在本地輸出跟蹤資訊。

  2、enabled 是否啟用跟蹤。

  3、pageOutput  指定在每一頁的結尾是否呈現跟蹤輸出。如果是 false ,則只能通過跟蹤工具 + 生產力訪問跟蹤輸出。

  4、requestLimit  指定在伺服器上儲存的跟蹤請求的數目。最大為10000,預設為10

  5、traceMode  指定顯示跟蹤資訊的順序。SortByCategory或 SortByTime(預設)

  關於更多可以參考

  http://msdn.microsoft.com/zh-cn/library/6915t83k%28VS.80%29.aspx

  下面以一個小Demo來說明怎麼使用Trace.axd來調試ASP.NET

  1. 建立一個Web項目,取名為WebTraceTest

  2. 編輯web.config檔案,添加trace節點(在)

  內容如下:

<trace enabled="true" localOnly="true"
pageOutput="true"
requestLimit="15"
mostRecent="true" />

  3. 建立一個頁面,取名為Test.aspx,在裡面增加一個文字框和一個按鈕(都是伺服器端的控制項)

  按下F5,開始調試,會發現出現如下介面

  5. 在文字框中輸入文字,如Alexis,點擊按鈕,會發現Form Collection中會有詳細的資訊,如下:

  說明:使用Trace.axd我們可以獲得以下資訊:

  Request Details:請求的詳細資料

  Trace Information:跟蹤資訊

  Control Tree:控制項樹

  Session State:工作階段狀態

  Application State:應用程式狀態

  Request Cookies Collection:請求Cookie集合

  Response Cookies Collection:響應Cookie集合

  Headers Collection:標題集合

  Response Headers Collection:響應標題集合

  Form Collection:表單集合

  Querystring Collection:QueryString集合(即Url中?後面的字串的資訊)

  Server Variables:伺服器變數

 將Visual Studio與一個運行中的進程串連

  當你按下F5對程式開始調試時,VS.NET會對項目進行產生(如果有必要的話)並以偵錯模式啟動程式。也就是說,只要項目位於debug版本的程式集中,VS.NET就與運行得程式之間建立了串連,以便對斷點等與調試相關的方法作出反應。

  不過有些時候,我們需要或者想要對正在運行得Visual Studio之外啟動的進程進行調試。當進程位於debug版本的程式集中,這是可以做到的。

  1. 選擇“工具—>調試進程”列出所有正在運行得程式,如

  2. 選擇自己感興趣的進程,點擊串連,此時Visual Studio自動切換到了偵錯模式。

  3. 開啟Progress視窗,發現我們剛剛選擇的進程在列表中,如

  這一技巧可以讓你對Windows服務進程進行調試。編寫Windows服務進程時,你無法按F5啟動調試,因為它們必須先通過管理工具安裝後啟動才能運行。如果你在偵錯模式下產生並安裝服務程式,就可以使用這一技巧進行調試。

  而且你可以對SQL預存程序使用同樣的方式進行調試。如果你安裝了SQL Server調試組件,並且有足夠的許可權,就可以串連到SQL Server的進程,並在伺服器中為預存程序設定斷點來一步步執行。

調試Visual Studio中的多重專案

  在實際開發中,我們往往分了許多層,有許多的項目集合在一個解決方案下。我們可以右擊要調試的項目選擇“調試-->運行新執行個體”來實現調試這個項目。我也可以右擊解決方案,選擇多項目調試,如

  我們還可以設定項目的期待順序。在用戶端/伺服器(CS結構)程式中,我們可以使用這一方法來確保伺服器端程式在用戶端程式之前運行。

  只在特定類型的異常時中斷

  一個健壯的程式會在運行時處理所有可能出現的異常。不過開發人員在調試複雜的程式時會覺得這樣有些麻煩。因為所有的異常都被處理掉了。在出現任何異常時,Visual Studio不會再進行處理,或者中斷代碼來對使用者作出提示。

  幸運的是Visual Studio有個選項可以讓開發人員指定他們關心的異常類型。選擇功能表列à調試à異常,或者使用快速鍵Ctrl+Alt+E。如

  我們可以看到一個樹狀結構列出所有VS可以監視到的異常。

  後面的兩個勾選框的意思分別為是否被拋出和使用者是否不處理。

  相關測試代碼下載:http://down.51cto.com/data/138874

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.