2.6 C#語法的學習(六) && 異常處理 && 調試


程序在遇到問題無法繼續執行時,會拋出異常告知開發/用戶。開發需要做的事情就是,在開發過程中,盡量減少異常發生的可能,同時完成異常捕獲,保證丑陋的異常不會直面用戶。
同時,異常內容也是調試過程中非常重要的訊息。

打斷點調試

調試的目的是檢驗我們的代碼是否有問題,代碼是否按照我們的想法在正確的執行。
打斷點調試則是最基本的調試方式。在調試過程中,配合LocalsImmediate WindowWatch等窗口可以很方便的調試。
它可以使程序停在我們指定的位置上,讓我們查看當前變量的情況、對數據進行修改、執行一些方法,拖動程序到我們想執行的代碼段。


具體的內容可以看這里,這篇文章講的很細很全。我們搜索的關鍵詞應該是“Vs debug” 、“Vs 調試” 。

使用try-catch捕獲異常

try-catch-finally可以理解為“嘗試做什么事………………如果出錯就……………………最后收尾工作完成………………”。
嘗試成功,則不執行“出錯”代碼段。嘗試失敗,就進入“出錯”代碼段。
無論失敗成功,一定會執行“收尾工作”。並且收尾工作finally是可選的,根據情況寫或者不寫。
比較細節的是,“出錯”的代碼段可以有多個,因為出錯的原因可以有很多個嘛~在catch(Exception ex)中,可以填寫不同的Exception,C#就會根據實際捕獲的Exception類型進入對應的catch代碼段,並且把異常對象賦值給ex
try-catch語句的詳細教程點擊這里
try-catch的應用非常廣泛:
1.調試的時候通過捕獲異常+打斷點的方式,查看異常詳情。
2.通過catch捕獲不同的異常,分情況執行不同的代碼。
比如:讀取數組並存儲(來自C# try catch finally:異常處理)

//定義存放5個整數的數組
int[] a = new int[5];
try
{
	for (int i = 0; i < a.Length; i++)
	{
		a[i] = int.Parse(Console.ReadLine());
	}
	for (int i = 0; i < a.Length; i++)
	{
		Console.Write(a[i] + " ");
	}
}
catch (FormatException f)
{
	Console.WriteLine("輸入的數字格式不正確!");
}
catch (OverflowException o)
{
	Console.WriteLine("輸入的值已經超出 int 類型的最大值!");
}
catch (IndexOutOfRangeException r)
{
	Console.WriteLine("數組越界異常!");
}
catch(Exception ex)
{
	Console.WriteLine("哇哦,出錯了!");
}

3.對於容易出問題的代碼段,加上try-catch之后發布程序。在catch代碼段中可以攔截異常,給用戶友好的提示,並且記錄日志,以便復現和分析問題。此方法特別適用於無法調試的情況。

延展:全局捕獲異常

是不是感覺try-catch很好用?那我是不是該給我的所有代碼加上try-catch,來保證它們不出錯?我告訴你,你會被其他開發打死的!
這樣代碼會很丑、很丑,不能忍那種。再來,try-catch是要消耗性能的(具體搜索“C# try catch 性能”),你說你一個“var i=1;”這樣的代碼加什么try-catch?
那你說,我就是希望可以捕獲到異常,讓程序更健壯啊……我有錯么?沒有,但是我們可以用更好的方式來解決——————全局捕獲異常。
當代碼出錯,並且這段代碼沒有在try-catch里面,則這個異常會被“全局捕獲異常”所捕獲。明白了么?try-catch是針對程序某一段代碼的縫紉機,全局捕獲異常是整個程序的縫紉機。try-catch沒有處理到的異常,就會交給全局捕獲異常來處理。全局捕獲異常就像最后一道防火牆一樣。
全局捕獲異常在不同的開發框架下不盡相同,我也記不住~記住有這個神器,會搜索就行,比如“WPF 全局捕獲異常”、“ASP .NET 全局捕獲異常”、“Winfrom 全局捕獲異常”,一搜一大把。


相同的,我們應該在全局捕獲異常的地方認真記錄出錯原因,並且攔截異常,向用戶顯示友好的提示。

打日志

打日志的本質是在程序運行過程中,記錄一些內容到文本文檔、數據庫等持續化存儲的地方。我們的關鍵詞是“C# 日志”、“.net 日志”。
打日志的目的也很多:
1.捕獲異常並記錄下詳細信息(方法名、參數、報錯位置等等),便於復現和解決問題。
2.因為業務需求,記錄一些流水性內容,比如某用戶在什么時候執行了什么操作調用了什么接口。
3.用於調試,特別是服務器上程序的調試。
......
C#日志比較出名的庫一個是log4net,一個是NLog。都是在nuget可以找到並安裝,可以直接使用的庫。像這種第三方庫,根據關鍵詞“log4net” 、“NLog”找到官網,在官方“Get Start”或者“Quick Start”里面都可以快速入門。英語不好的同學也可以選擇中文的博客來進行學習。
在這些完善好的日志系統中,日志的內容是分級的,一般分為TraceDebugInfoErrorFatal。開發者可以根據自己感興趣的日志層級進行靈活設置。

延展:自行實現日志功能的姿勢和可行性

當然你也可以選擇自己實現日志記錄。想想日志實際上是什么?最簡單的就是文本文檔記錄一些內容。
“文本文檔記錄”,是不是“C# 創建txt文本”?老規矩,我們搜一搜:

是不是瞬間覺得簡單了~所以,不要害怕,這些都是無數人踩過的坑。
創建txt之后,是不是就是“讀”和“寫”日志的問題了——————“C# 讀寫txt”,就可以找到答案(甚至上一個關鍵詞“C# 創建txt文本”的部分搜索結果就已經有答案了)。
再來,數據庫記錄日志,是不是實際上就是“建立日志表-插入日志記錄”,難么?不難,就是一些數據庫的操作而已。
那既然這么簡單,為什么大家會選用log4net、NLog這樣第三方的庫,而不是自己實現呢?
首先,開發者普遍認為“不要重復造輪子”。在這個問題中,log4net、NLog就是別人造好的、可以直接使用的輪子,既然可以直接上路,為什么還要努力造自己的輪子?而且你造出來大概率還沒有現有的輪子好看、好用,所以還是直接用吧!
再來,我剛剛說的實現日志,只是最簡單的情況,實際上你去看log4net、NLog的源代碼或者文檔,你會發現“記錄日志”這件事被他們弄得“很復雜”。
比如剛剛說的分級問題;比如不同時間的日志是放在一個文檔里面還是分日期/分月/分小時放在不同的文檔里面,文檔多了是不是要分文件夾;比如一個文檔的最大大小是否有限制,如果超過了這個限制應該怎么辦,是新建一個文檔繼續記錄還是覆蓋當前文檔前面的記錄;怎么讓這些需要配置的地方變得靈活;不同框架的支持甚至是不同IDE的支持(如果有,這個多適用於一些前端顯示化框架)………………
你跟我說這些你自己寫么?可以但沒必要啊,直接用吧,感興趣還可以看看人家代碼是怎么寫的,給他們提提意見(Issures),為項目添磚加瓦(Pull Request),多好。
最后,是代碼維護成本的問題。像這些庫都是有開發者在一直持續更新的,這保證了即使你的程序之后升版本、需要遷移,你只需要更新這些庫,可能還會改點代碼就可以繼續使用它們了。即使改代碼也不用擔心,官網大概率會出遷移方面的說明文檔,照做即可。而如果是自己寫呢?你可能就需要重新寫一套記錄日志的代碼了。

遠程調試

有時候我們會遇到在開發機運行ok,發布到服務器就GG的問題。然后百思不得其解,然后崩潰o(≧口≦)o
這時候不要慌張,我們可以遠程調試。搜索關鍵詞“C# 遠程調試”、“VS 遠程調試”都可以。
它可以讓我們像在開發機上調試程序一樣,調試服務器上的程序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM