国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#調(diào)試入門篇

2019-11-17 03:16:33
字體:
供稿:網(wǎng)友

C#調(diào)試入門篇

DotNet程序的調(diào)試,是DotNet程序員必備的技能之一,開發(fā)出穩(wěn)定的程序、解決程序的疑難雜癥都需要很強(qiáng)大的調(diào)試能力。DotNet調(diào)試有很多方法和技巧。現(xiàn)在本文就介紹一下借助DebugView工具進(jìn)行調(diào)試的方法,以及由DebugView引申出來的知識點(diǎn)。

DebugView

DebugView是一個查看調(diào)試信息的非常棒的工具,支持Debug、Release模式編譯的程序,甚至支持內(nèi)核程序,而且能夠定制各種過濾條件,讓你只看到關(guān)心的輸出信息,而且可以定制高亮顯示的內(nèi)容等等,非常方便。

debugview

捕捉Release模式的Win32程序輸出的調(diào)試信息,需要選中Capture Global Win32選項(xiàng):

debugview_release

過濾與高亮功能

debugview_過濾與高亮

可以通過include、exclude設(shè)置過濾條件,包含指定字符串的輸出信息將會被過濾。還可以通過exclude條件過濾掉對應(yīng)進(jìn)程ID的調(diào)試信息。多個條件使用“;”分隔,而且支持“*”通配符。

遠(yuǎn)程調(diào)試

DebugView支持遠(yuǎn)程捕捉調(diào)試信息。首先在遠(yuǎn)程機(jī)器上通過如下命令啟動DebugView:

DebugView.exe /a /t /g /s

這樣,DebugView就會以服務(wù)的方式運(yùn)行,如下圖:

debugview服務(wù)

然后在本地機(jī)器上啟動DebugView,并通過Connect連接到遠(yuǎn)程機(jī)器的DebugView,當(dāng)遠(yuǎn)程機(jī)器中有調(diào)試信息輸出時,本地就會捕獲到,并展示出來:

debugview_connect

輸出信息到DebugView的幾種方式

DebugView的一些功能是不是讓你心動了呢。俗話說心動不如行動,但是在行動之前,首先要知道C#如何將調(diào)試信息輸出到DebugView中。

通過編程輸出一些調(diào)試信息到DebugView中,一共有三種方式:

  • Debug.WriteLine
  • Debugger.Log
  • Kernal32.dll中的OutputDebugString方法

一、Debug.WriteLine

通過Debug.WriteLine可以將調(diào)試信息寫入到DebugView中,如下:

Debug.WriteLine("這是調(diào)試信息");

效果如下:

Debug_DebugView

不過此方式只能在Debug模式下有效。具體原因下面會詳細(xì)介紹。

二、Debugger.Log

Debug.WriteLine已經(jīng)很好用了,唯一的缺點(diǎn)就是在Release模式下無效。那么在Release模式下就可以使用Debugger.Log方法,示例如下:

Debugger.Log(0, null, "這是Debugger.Log輸出的調(diào)試信息");

三、Kernel32.dll中的OutputDebugString方法

做C++開發(fā)的應(yīng)該知道可以通過OutputDebugString這個API開實(shí)現(xiàn)輸出調(diào)試信息到DebugView中吧。那么C++能做的,C#也能做。可以通過PInvoke的方式引入此方法,這個API屬于Kernel32.dll,如下聲明:

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]public static extern void OutputDebugString(string message);

然后就可以通過調(diào)用此方法,將調(diào)試信息輸出到DebugView中。

DebugView與日志框架比較

可能有人會說,DebugView能做的事情,我用log4Net,NLog等日志框架也能做,為什么要用DebugView呢?

問的好,那么我就根據(jù)平時使用DebugView的經(jīng)驗(yàn)來給你一個用DebugView的理由:

  • DebugView使用非常方便。相比于日志框架龐大的體系,DebugView的使用可謂是十分的簡單方便。DebugView只有幾百K的大小,占用空間幾乎可以忽略不計(jì)。從官網(wǎng)下載后,直接運(yùn)行exe,幾乎不需要任何配置就可以正常使用。而相比于DebugView,日志框架可以算的上龐然大物。而當(dāng)你從官網(wǎng)獲得log4Net后,需要進(jìn)行各種繁雜的配置。甚至你要花上幾天時間專門學(xué)習(xí)一下這套框架。由此可以看出DebugView的使用實(shí)在是方便的不能再方便。
  • DebugView是可視化工具,支持各種過濾和高亮。DebugView可以通過過濾條件來過濾不關(guān)心的信息,只顯示相關(guān)的調(diào)試信息。而日志框架輸出的是文件等文本信息,這些信息會包含程序運(yùn)行過程中的所有信息,雖然可以通過配置文件來指定只輸出哪一類信息,但是不如DebugView來的方便簡單。
  • DebugView可以實(shí)時監(jiān)視。DebugView中有“自動滾動”的功能,程序中輸出的調(diào)試信息,基本上瞬間就會在DebugView中展示出來,當(dāng)由于大量信息導(dǎo)致DebugView中的文本框滿了后,DebugView可以通過自動滾動滾動條,讓你隨時都可以看到最新的一條信息,達(dá)到類似監(jiān)視的效果。而日志框架由于其寫文本的特性,很難達(dá)到這種效果,即使能達(dá)到,相信也是需要對日志框架相當(dāng)清楚了解,才能完成這個效果。

這些理由應(yīng)該足以讓你使用DebugView了吧。使用DebugView的理由肯定還不止這些,如果你有更好的理由,還請分享出來。

當(dāng)然,DebugView與日志框架,每個都有每個的用途。通過DebugView的方式,只適合短暫的調(diào)試,而正式發(fā)布的網(wǎng)站或者軟件,需要一套記錄程序長期以來的運(yùn)行狀態(tài)的工具,那么就非日志框架莫屬了。所以DebugView與日志框架,要在合適的地方,發(fā)揮他們最大的功效。

聲明

Log4Net等日志框架,功能足夠強(qiáng)大,也足夠豐富,相信上面說到的DebugView的功能,也可以通過日志框架來實(shí)現(xiàn)。但是和DebugView比較起來,會相對復(fù)雜一些。所以上面說到的使用DebugView的理由是基于方便性的比較,DebugView有足夠的方便性來讓你選擇使用他。

ConditionalAttribute詳解與條件編譯

說到調(diào)試,那么肯定有開發(fā)人員遇到這種情況,開發(fā)產(chǎn)品的時候,遇到一些問題,就在代碼中加入了大量的調(diào)試輸出信息,比如通過Console.WriteLine、MessageBox.Show或者通過Ilog.Log記錄日志,甚至臨時改變邏輯來驗(yàn)證邏輯的正確性等。經(jīng)過這些調(diào)試信息的幫助,終于解決了產(chǎn)品的問題。但此時又遇到了新的問題,產(chǎn)品最終發(fā)布的時候,肯定是不能有這些調(diào)試信息的,可是已經(jīng)加了這么多調(diào)試信息,難道要全部刪除掉嗎。這顯然不是一個好辦法,這么多代碼,手一抖,很容易就刪除了不相關(guān)的代碼,造成不可預(yù)估的后果。

做過C/C++開發(fā)的,可以從各種跨平臺的開源庫中看到,一堆一堆的#if....#else....#endif,這就是條件編譯,這也是C/C++跨平臺所依賴的最基本的東西,在linux系統(tǒng),編譯這段代碼,在Windows系統(tǒng)又編譯那段代碼,最終實(shí)現(xiàn)了代碼級別的跨平臺。

那么C#中有沒有類似的功能呢,答案當(dāng)然是有,而且有兩種:

  • 通過給方法加上ConditionalAttribute特性
  • 使用#if..#else..#endif,來控制代碼的編譯

ConditionalAttribute特性

下面是ConditionalAttribute的構(gòu)造函數(shù):

public ConditionalAttribute(    string conditionString)

構(gòu)造函數(shù)中的參數(shù)conditionString,是一個區(qū)分大小寫的條件編譯符號的字符串。

上面提到Debug.WriteLine時,說到這個功能只在Debug模式下才有用,Release下就不起作用了。

我們從MSDN中看一下Debug.WriteLine的說明:

[ConditionalAttribute("DEBUG")]public static void WriteLine(    string message)

由此也就明白了Debug.WriteLine只能在Debug模式下使用,而在Release模式下無效的原因了。

條件編譯#if..#else..#endif

C/C++中有#if..#else..#endif,C#中也有這些,他們都被稱為預(yù)處理器。通過預(yù)定義的條件編譯符號,來控制編譯時編譯哪部分代碼。如下:

public bool Haspermission(string userName){#if DEBUG    //Debug模式下,不需要做權(quán)限判斷,直接返回true    return true;#else    //Release模式下,只有sa用戶才有權(quán)限    if (!string.IsNullOrEmpty(userName) && userName == "sa")    {        return true;    }    else    {        return false;    }#endif}

預(yù)定義的Debug宏在什么地方

說到條件編譯,是不是只有DEBUG 和 RELEASE兩種情況呢,如果是這種情況的話,那也就是說DEBUG和RELEASE兩種情況是定義好了的,俗話說就是“做死了”,這是作死的節(jié)奏啊。不作死就不會死,至少VS在這點(diǎn)上還沒有作死。

讓我們來一步步揭開DEBUG的面紗。

既然是條件編譯,那么就應(yīng)該和編譯選項(xiàng)有關(guān)。我們知道C#項(xiàng)目,有一個屬性頁,可以設(shè)置很多編譯的選項(xiàng),如下:

VS項(xiàng)目生成屬性頁

從圖中看到,條件編譯是用的DEBUG常量,或者稱為DEBUG條件編譯符號,是在這個編譯生成選項(xiàng)中定義的,如果去掉這個定義,那么編譯后的HasPermission方法就會根據(jù)用戶名進(jìn)行權(quán)限檢查,程序中通過Debug.WriteLine輸出的調(diào)試信息也會輸出到DebugView中,也就相當(dāng)于Release模式下的效果。

其實(shí)DEBUG常量與Debug、Release模式并無太大的關(guān)系,唯一的關(guān)系就是,VS生成的項(xiàng)目中,Debug模式下,默認(rèn)會選中“定義DEBUG常量”,而Release模式下,默認(rèn)不會選中。也就是說,Debug模式,默認(rèn)會定義DEBUG常量,而Release不會,如下圖:

Debug_Release默認(rèn)配置

既然DEBUG常量與Debug模式無本質(zhì)上的關(guān)聯(lián),那么為什么說到Debug,就認(rèn)為DEBUG呢。道理其實(shí)很簡單,世上本無路,走的人多了,便成了路。本來這個DEBUG常量只是Debug模式下的默認(rèn)預(yù)定義的常量,只是因?yàn)榇蠹伊?xí)慣了,并且對它的這種預(yù)定義還比較認(rèn)可,時間久了,就自然而然認(rèn)為DEBUG就代表Debug模式。

雖然我們可以通過去掉DEBUG常量,來使條件編譯在Debug模式下達(dá)到Release模式的效果,但是建議最好不要這樣做,因?yàn)檫@就像是大家普遍都認(rèn)可的一個約定,如果你一反常態(tài),不遵守這個約定,對于程序,編譯沒有問題,但是后續(xù)維護(hù)肯定會相當(dāng)麻煩,所以還請大俠手下留情。

使用自定義的編譯常量

DEBUG常量作為一種普遍的約定,最好不要打破。如果有除DEBUG外的條件編譯需要,可以使用自定義的編譯常量。

自定義編譯常量有兩種方法:

  • 通過編譯生成屬性頁中的條件編譯輸入框,定義自己的編譯常量。
  • 在代碼中使用#define預(yù)處理,來定義編譯常量
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹤岗市| 古交市| 西藏| 资阳市| 苏州市| 绍兴县| 茌平县| 和顺县| 新郑市| 汪清县| SHOW| 贵南县| 彰武县| 柳州市| 安康市| 林州市| 蒙城县| 当阳市| 吉安县| 郎溪县| 图片| 汉寿县| 秭归县| 博客| 康平县| 安徽省| 裕民县| 徐州市| 波密县| 南通市| 虎林市| 阳西县| 贡觉县| 轮台县| 海宁市| 东光县| 瓦房店市| 年辖:市辖区| 肇庆市| 融水| 柘城县|