新聞中心
我們?cè)谧龀绦蜷_發(fā)時(shí),難免會(huì)遇到錯(cuò)誤異常。如何快速地找到出錯(cuò)的地方、分析錯(cuò)誤的原因以及找到解決問題的方案,是許多初級(jí)程序員困擾的問題,這也正是經(jīng)驗(yàn)的寶貴之處。下面我將簡(jiǎn)單介紹在Visual Studio中調(diào)試以及一些高級(jí)的調(diào)試和常見的錯(cuò)誤。

為拉薩等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及拉薩網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、拉薩網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
PS:如無特別說明Visual Studio均指Dev10即Visual Studio 2010。
入門篇
假設(shè)你是有著.Net平臺(tái)的程序員,并且使用Visual Studio 做為開發(fā)工具。
斷點(diǎn):最簡(jiǎn)單的一種,設(shè)置一個(gè)斷點(diǎn),程序執(zhí)行到那一句就自動(dòng)中斷進(jìn)入調(diào)試狀態(tài)。設(shè)置斷點(diǎn),在你覺得有問題的代碼行,左側(cè)單擊,會(huì)出現(xiàn)紅色的紅點(diǎn)即斷點(diǎn)。
啟動(dòng)調(diào)式:按F5,或者菜單欄---調(diào)式---開始調(diào)試,或者工具欄的圖標(biāo)
快速監(jiān)視:快速查看變量或者表達(dá)式的值,也可以自定義表達(dá)式進(jìn)行計(jì)算
單步執(zhí)行
有三種,一種是每次執(zhí)行一行(F10);一種是每次執(zhí)行一行,但遇到函數(shù)調(diào)用就會(huì)跳到被調(diào)用的函數(shù)里(F11);一種是直接執(zhí)行當(dāng)前函數(shù)里剩下的指令,返回上一級(jí)函數(shù)(Shift+F11)。
還有一種后悔藥,設(shè)為下一句(Set Next Statement),即下一句會(huì)被執(zhí)行的語句(右擊設(shè)置或者快捷鍵:Ctrl+Shift+F10),但要注意在調(diào)試與數(shù)據(jù)有關(guān)的時(shí)候,設(shè)置下一句有可能會(huì)報(bào)異常。如在調(diào)試向DataTable中添加行的時(shí)候,已經(jīng)存在的行不能重復(fù)被添加到DataTable中。
監(jiān)視
調(diào)試器可能會(huì)自動(dòng)列出一些相關(guān)變量的值,但是你可能還關(guān)心其它變量的值,可以添加對(duì)這些變量的監(jiān)視。還可以監(jiān)視一個(gè)表達(dá)式的值,比如a+b。但是,這個(gè)表達(dá)式最好不要修改變量的值,比如監(jiān)視a++都會(huì)導(dǎo)致監(jiān)視時(shí)修改了a的值,影響了程序的運(yùn)行結(jié)果。
調(diào)試技巧篇
使用快捷鍵會(huì)大大提升我們的調(diào)試效率,常用的調(diào)試快捷鍵:
F5 啟動(dòng)調(diào)試
F10 執(zhí)行下一行代碼,但不執(zhí)行任何函數(shù)調(diào)用。
F11 在執(zhí)行進(jìn)入函數(shù)調(diào)用后,逐條語句執(zhí)行代碼。
Shift + F11 執(zhí)行當(dāng)前執(zhí)行點(diǎn)所處函數(shù)的剩余行。
Shift + F5 停止運(yùn)行程序中的當(dāng)前應(yīng)用程序。可用于“中斷”模式和“運(yùn)行”模式。
拖動(dòng)斷點(diǎn)(感謝 圣殿騎士的提醒)
在調(diào)試中,我們可以拖動(dòng)斷點(diǎn),使得程序運(yùn)行到我們想要運(yùn)行的地方。通常是用來驗(yàn)證這段代碼對(duì)程序的運(yùn)行結(jié)果有沒有影響的。因?yàn)槲覀兺蟿?dòng)代碼,則被過濾的代碼就不會(huì)執(zhí)行,將它跟原來的相比,可以看出去掉這段代碼有什么影響
條件中斷
假如你寫了個(gè)for循環(huán),而且循環(huán)的次數(shù)比較多,如下代碼,現(xiàn)在我們知道在i=50的時(shí)候會(huì)有異常,那我們不可能按50次F5去調(diào)試這代碼,不然這效率….
- 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,即剛進(jìn)入for循環(huán)中,我們?cè)O(shè)置將i改為49并回車,再調(diào)試一次,會(huì)發(fā)現(xiàn)i=50; 如下圖
當(dāng)然我們也可以直接在代碼里寫代碼以達(dá)到這個(gè)目的,代碼如下
- 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");
- }
- }
- }
使用了調(diào)試中的Assert(斷言),當(dāng)執(zhí)行程序后會(huì)彈出如下的提示框,點(diǎn)擊Ingore(忽略)即可,
Immediate Window
Immediate window在調(diào)試的時(shí)候計(jì)算表達(dá)式的值、執(zhí)行語句、打印變量的值等。我們輸入命令(注意一定要以“>”開頭),會(huì)有智能提示,而且命名都是自解釋型。
如,我們現(xiàn)在想要知道i的值,可以輸入命名>Debug.Print i(也可以簡(jiǎn)單的使用>? i),如下圖
Immediatewindow還有更強(qiáng)大的用法,計(jì)算方法的返回值(如果有的話)
如果有這個(gè)的函數(shù)
- int MethodValue(int a)
- {
- if (a==1)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
我們可以使用Immediate命令 >? class.Method(args) 去調(diào)用這個(gè)方法,如下圖
其中p是當(dāng)前類的實(shí)例(因?yàn)镸ethodValue是類的方法,注意?和表達(dá)式之間要有空格)
對(duì)于一些實(shí)時(shí)性很高的程序(如socket)使用 Debug.Write()把錯(cuò)誤寫到日志文件中,.Net可以將Debug信息寫到你指定的文件中,記住,寫進(jìn)出的信息不一定是出錯(cuò)的信息,也可以是你的程序的運(yùn)行的一些重要信息,當(dāng)你調(diào)試過程中發(fā)現(xiàn)某個(gè)模塊出了問題,但是不能決定位置,那你就可以使用這個(gè)方法,如果是一天才出一個(gè)錯(cuò)誤,那你就更要使用這個(gè)方法。
#p#
實(shí)例篇
涉及到WS(WebServices)的調(diào)試
在基于WinForm的實(shí)際開始開發(fā)中,我們往往采用WS用做數(shù)據(jù)的傳遞,我們?cè)谇芭_(tái)獲取收集數(shù)據(jù),通過WS將數(shù)據(jù)傳遞給后臺(tái),后臺(tái)做相應(yīng)的業(yè)務(wù)邏輯處理后,會(huì)持久到數(shù)據(jù)庫中。而往往我們又會(huì)在WS中寫一些相關(guān)的代碼,如身份驗(yàn)證、日志記錄、提示信息等,怎樣去調(diào)試這些代碼呢。
涉及到JavaScript的調(diào)試
許多程序員為調(diào)試JavaScript感到困惑不已,因?yàn)闆]有一款很好的調(diào)試工具。一些人喜歡使用FireBug來調(diào)試JavaScript,確實(shí)是一個(gè)不錯(cuò)的選擇,F(xiàn)irebug提供了許多的JavaScript信息,是一款不錯(cuò)的調(diào)試JavaScript的工具。下面我將會(huì)介紹如何使用Visual Studio調(diào)試JavaScript,Visual Studio中調(diào)試JS跟調(diào)試C#差不多,都是設(shè)置斷點(diǎn),不同的是我們?cè)诓榭丛刂档臅r(shí)候需要注意點(diǎn)。
涉及到Ajax的調(diào)試
現(xiàn)在ajax已經(jīng)十分的流行,但是隨之而來的即調(diào)試?yán)щy,大部分初級(jí)程序員不知道如何有效地從前臺(tái)調(diào)試到后臺(tái)代碼,以至出了很多不完善的ajax應(yīng)用。
下面以一個(gè)簡(jiǎn)單的實(shí)例來介紹如何使用Visual Studio調(diào)試JavaScript。實(shí)例是使用Ajax驗(yàn)證用戶登錄,如果驗(yàn)證通過,則提示“登錄成功”,否則提示“登錄失敗”。
下面是主要的代碼,我們使用jQuery來實(shí)現(xiàn)ajax,并且在后臺(tái)文件中故意出錯(cuò)。
正確的用戶名和密碼是admin和1
調(diào)試方法如下,在后臺(tái)入口處設(shè)置斷點(diǎn),然后在前臺(tái)js中調(diào)用后臺(tái)的方法處設(shè)置斷點(diǎn),然后按F5啟動(dòng)調(diào)試,當(dāng)我們輸入用戶名、密碼后,點(diǎn)擊登錄后會(huì)發(fā)現(xiàn),前臺(tái)斷點(diǎn)被觸發(fā)了。
按F5繼續(xù)調(diào)試,有時(shí)候會(huì)跳到j(luò)Query的源碼中,不管他,繼續(xù)F5,會(huì)發(fā)現(xiàn)執(zhí)行到后臺(tái)中的斷點(diǎn)中,如下圖
而后臺(tái)代碼的調(diào)試是十分簡(jiǎn)單的。(PS:有時(shí)候無需在前臺(tái)設(shè)置斷點(diǎn)也可直接進(jìn)入后臺(tái)的調(diào)試,如何不行的話,在前臺(tái)html文件或者aspx文件中認(rèn)為有可能出錯(cuò)的地方設(shè)置斷點(diǎn),一步步調(diào)試)
一些調(diào)試中出現(xiàn)的常見錯(cuò)誤(會(huì)陸續(xù)更新):
1. 我們調(diào)試到某一句代碼的時(shí)候,突然莫名奇妙的跳出來了,其實(shí)是剛剛執(zhí)行的這一句話有異常,我們可以使用try…catch進(jìn)行異常捕獲,看看異常原因是什么,然后做相應(yīng)的處理
2. 在ADO.NET,我們會(huì)使用ds.Merge()方法進(jìn)行合并內(nèi)存表,如果有異常的話,一般有以下三種情況
A.其中一張表中有兩行一模一樣的數(shù)據(jù),包括主鍵
B.這兩張表的結(jié)構(gòu)不一致
C.兩張表中某個(gè)字段的類型不匹配,如字段age在A表中式string,而在B表中確是Decimal
#p#
斷點(diǎn)篇
命中次數(shù)(Hit Counts)
右擊斷點(diǎn),可以設(shè)置Hit Counts(命中次數(shù)),會(huì)彈出如下的對(duì)話框
當(dāng)條件滿足的時(shí)候斷點(diǎn)會(huì)被命中(即即將被執(zhí)行),這個(gè)命中次數(shù)是斷點(diǎn)被命中的次數(shù)。默認(rèn)是始終break,選項(xiàng)有如下的幾種:始終break;當(dāng)命中次數(shù)達(dá)到多少次時(shí)break;當(dāng)命中次數(shù)是多少的倍數(shù)時(shí)break;當(dāng)命中次數(shù)大于等于多少的時(shí)候break。
于是在上篇中的條件也可以這樣實(shí)現(xiàn),設(shè)置命中次數(shù)等于50的時(shí)候break,按F5后,斷點(diǎn)被觸發(fā),此時(shí)i=50。
斷點(diǎn)過濾器
我們可以限制斷點(diǎn)在特定的處理器和進(jìn)程中??梢栽O(shè)置機(jī)器名、進(jìn)程id、進(jìn)程名、線程id、線程名中的某些條件來過濾一些斷點(diǎn)。
注意:ThreadId需要特別說明一下,ThreadId并不是托管程序中,.NET 框架中System.Threading.Thread.ManagedThreadId,兩者不能等同。簡(jiǎn)單來說,ManagedThreadId是線程在CLR中的標(biāo)識(shí)符,而ThreadId卻是線程在操作系統(tǒng)中的標(biāo)識(shí)符。因此ThreadId需要從調(diào)試器中的“Threads”窗口中獲取。
斷點(diǎn)條件
我們可以設(shè)置斷點(diǎn)達(dá)到的條件,如下圖,我們?cè)O(shè)置表達(dá)式為i==5(注意是判相等,而不是賦值的等于),按F5,斷點(diǎn)再次被觸發(fā),此時(shí)i=50。
還有一個(gè)選項(xiàng)是已經(jīng)被改變,則里面條件是具體的變量,如我們的代碼如下
private void ConditionDebug()
{
int hitCount = 0;
for (int i = 0; i < 100; i++)
{
if (i==49)
{
hitCount = 1;
}
}
Console.Write("Hit Count={0}", hitCount);
}我們?cè)诖a里如果i==49,就將hitCount的值改變,同時(shí)設(shè)置斷點(diǎn)的條件為
則當(dāng)斷點(diǎn)再次被觸發(fā)的時(shí)候此時(shí)i=50。這個(gè)通常被用在找變量的時(shí)在什么時(shí)候發(fā)生改變。
斷點(diǎn)的位置
可以設(shè)置斷點(diǎn)的位置,如下圖,設(shè)置程序到達(dá)那個(gè)文件的第幾行第幾個(gè)字符時(shí)觸發(fā)斷點(diǎn)。
斷點(diǎn)觸發(fā)時(shí)…
我們可以設(shè)置斷點(diǎn)到達(dá)時(shí)做一些其他的事情,如打印消息,運(yùn)行一個(gè)宏。
自定義調(diào)用堆棧
堆棧跟蹤時(shí)vs一步步執(zhí)行你的程序是對(duì)當(dāng)前的方法調(diào)用繼承關(guān)系的直觀顯示。在調(diào)試程序時(shí),我們會(huì)經(jīng)過一個(gè)又一個(gè)方法,包括方法的嵌套調(diào)用。堆棧跟蹤會(huì)對(duì)這當(dāng)中的每一層方法作出記錄。選擇“調(diào)試-->窗口-->調(diào)用堆?!?,或者是快捷鍵Ctrl+Alt+C就可以看到當(dāng)前的堆棧跟蹤狀態(tài)。這里會(huì)將每個(gè)方法單獨(dú)顯示為一行,并且?guī)в行刑?hào)和參數(shù)值。每一個(gè)新的方法調(diào)用被稱為堆棧幀。
堆棧跟蹤是廣為人知的調(diào)試工具,它的優(yōu)點(diǎn)在于你可以雙擊任意一行跳轉(zhuǎn)到程序中該層調(diào)用方法的代碼。于是你可以看到程序是如何執(zhí)行到這一位置的,同時(shí)可以看到方法接受的參數(shù)值。并且可以使用Ctrl+C將一個(gè)或者全部堆棧幀復(fù)制到剪貼板,并將這個(gè)方法的調(diào)用信息發(fā)送給工作伙伴。
項(xiàng)目屬性中的Debug選項(xiàng)卡
如果你的項(xiàng)目是Console項(xiàng)目(控制臺(tái)應(yīng)用程序)或者是WinForm項(xiàng)目,則右擊項(xiàng)目解決方案,選擇屬性,會(huì)出來如下的項(xiàng)目屬性窗體。
我們可以設(shè)置“啟動(dòng)動(dòng)作”、“啟動(dòng)選項(xiàng)”和“是否啟用調(diào)試”。
Start Action有三個(gè)選擇項(xiàng):
Start Project:默認(rèn)選項(xiàng),設(shè)置為啟動(dòng)項(xiàng)目
Start external program:調(diào)試的時(shí)候啟動(dòng)內(nèi)部程序
Start browser with URL:調(diào)試的時(shí)候打開URL地址
使用Trace.axd調(diào)試ASP.NET
在以前asp時(shí)候,我們?yōu)榱瞬榭茨硞€(gè)變量的值,通常會(huì)使用Response.Write方法??赡墁F(xiàn)在許多ASP.NET程序員也習(xí)慣在后臺(tái)使用Response.Write方法將變量的值寫出來,其實(shí)微軟提供了很好的調(diào)試工具,即Trace.axd。它的功能主要是:配置 ASP.NET 代碼跟蹤服務(wù)以控制如何收集、存儲(chǔ)和顯示跟蹤結(jié)果。
關(guān)鍵的幾個(gè)選項(xiàng):
1、localOnly 默認(rèn)為false。這個(gè)很好理解。如果為true,只在本地輸出跟蹤信息。
2、enabled 是否啟用跟蹤。
3、pageOutput 指定在每一頁的結(jié)尾是否呈現(xiàn)跟蹤輸出。如果是 false ,則只能通過跟蹤實(shí)用工具訪問跟蹤輸出。
4、requestLimit 指定在服務(wù)器上存儲(chǔ)的跟蹤請(qǐng)求的數(shù)目。最大為10000,默認(rèn)為10
5、traceMode 指定顯示跟蹤信息的順序。SortByCategory或 SortByTime(默認(rèn))
關(guān)于更多可以參考
http://msdn.microsoft.com/zh-cn/library/6915t83k%28VS.80%29.aspx
下面以一個(gè)小Demo來說明怎么使用Trace.axd來調(diào)試ASP.NET
1. 建立一個(gè)Web項(xiàng)目,取名為WebTraceTest
2. 編輯web.config文件,添加trace節(jié)點(diǎn)(在)
內(nèi)容如下:
pageOutput="true" requestLimit="15" mostRecent="true" /> 3. 新建一個(gè)頁面,取名為Test.aspx,在里面增加一個(gè)文本框和一個(gè)按鈕(都是服務(wù)器端的控件) 按下F5,開始調(diào)試,會(huì)發(fā)現(xiàn)出現(xiàn)如下界面 5. 在文本框中輸入文字,如Alexis,點(diǎn)擊按鈕,會(huì)發(fā)現(xiàn)Form Collection中會(huì)有詳細(xì)的信息,如下: 說明:使用Trace.axd我們可以獲得以下信息: Request Details:請(qǐng)求的詳細(xì)信息 Trace Information:跟蹤信息 Control Tree:控件樹 Session State:會(huì)話狀態(tài) Application State:應(yīng)用程序狀態(tài) Request Cookies Collection:請(qǐng)求Cookie集合 Response Cookies Collection:響應(yīng)Cookie集合 Headers Collection:標(biāo)頭集合 Response Headers Collection:響應(yīng)標(biāo)頭集合 Form Collection:窗體集合 Querystring Collection:QueryString集合(即Url中?后面的字符串的信息) Server Variables:服務(wù)器變量 將Visual Studio與一個(gè)運(yùn)行中的進(jìn)程連接 當(dāng)你按下F5對(duì)程序開始調(diào)試時(shí),VS.NET會(huì)對(duì)項(xiàng)目進(jìn)行生成(如果有必要的話)并以調(diào)試模式啟動(dòng)程序。也就是說,只要項(xiàng)目位于debug版本的程序集中,VS.NET就與運(yùn)行得程序之間建立了連接,以便對(duì)斷點(diǎn)等與調(diào)試相關(guān)的方法作出反應(yīng)。 不過有些時(shí)候,我們需要或者想要對(duì)正在運(yùn)行得Visual Studio之外啟動(dòng)的進(jìn)程進(jìn)行調(diào)試。當(dāng)進(jìn)程位于debug版本的程序集中,這是可以做到的。 1. 選擇“工具—>調(diào)試進(jìn)程”列出所有正在運(yùn)行得程序,如下圖 2. 選擇自己感興趣的進(jìn)程,點(diǎn)擊連接,此時(shí)Visual Studio自動(dòng)切換到了調(diào)試模式。 3. 打開Progress窗口,發(fā)現(xiàn)我們剛剛選擇的進(jìn)程在列表中,如下圖 這一技巧可以讓你對(duì)Windows服務(wù)進(jìn)程進(jìn)行調(diào)試。編寫Windows服務(wù)進(jìn)程時(shí),你無法按F5啟動(dòng)調(diào)試,因?yàn)樗鼈儽仨毾韧ㄟ^管理工具安裝后啟動(dòng)才能運(yùn)行。如果你在調(diào)試模式下生成并安裝服務(wù)程序,就可以使用這一技巧進(jìn)行調(diào)試。 而且你可以對(duì)SQL存儲(chǔ)過程使用同樣的方式進(jìn)行調(diào)試。如果你安裝了SQL Server調(diào)試組件,并且有足夠的權(quán)限,就可以連接到SQL Server的進(jìn)程,并在服務(wù)器中為存儲(chǔ)過程設(shè)置斷點(diǎn)來一步步執(zhí)行。 調(diào)試Visual Studio中的多個(gè)項(xiàng)目 在實(shí)際開發(fā)中,我們往往分了許多層,有許多的項(xiàng)目集合在一個(gè)解決方案下。我們可以右擊要調(diào)試的項(xiàng)目選擇“調(diào)試-->運(yùn)行新實(shí)例”來實(shí)現(xiàn)調(diào)試這個(gè)項(xiàng)目。我也可以右擊解決方案,選擇多項(xiàng)目調(diào)試,如下圖 我們還可以設(shè)置項(xiàng)目的期待順序。在客戶端/服務(wù)器(CS結(jié)構(gòu))程序中,我們可以使用這一方法來確保服務(wù)器端程序在客戶端程序之前運(yùn)行。 只在特定類型的異常時(shí)中斷 一個(gè)健壯的程序會(huì)在運(yùn)行時(shí)處理所有可能出現(xiàn)的異常。不過開發(fā)者在調(diào)試復(fù)雜的程序時(shí)會(huì)覺得這樣有些麻煩。因?yàn)樗械漠惓6急惶幚淼袅?。在出現(xiàn)任何異常時(shí),Visual Studio不會(huì)再進(jìn)行處理,或者中斷代碼來對(duì)用戶作出提示。 幸運(yùn)的是Visual Studio有個(gè)選項(xiàng)可以讓開發(fā)者指定他們關(guān)心的異常類型。選擇菜單欄à調(diào)試à異常,或者使用快捷鍵Ctrl+Alt+E。如下圖
我們可以看到一個(gè)樹狀結(jié)構(gòu)列出所有VS可以監(jiān)視到的異常。
后面的兩個(gè)勾選框的意思分別為是否被拋出和用戶是否不處理。
相關(guān)測(cè)試代碼下載:http://down./data/138874
網(wǎng)站題目:C#調(diào)試從入門到精通
網(wǎng)頁URL:http://m.fisionsoft.com.cn/article/cdiipjd.html


咨詢
建站咨詢
