推薦:談對程序開發(fā)中異常的處理從接觸異常開始我就弄不明白她,不會用她,想在系統(tǒng)中是異常機制發(fā)揮的淋漓盡致,進行了很多嘗試,利用異常控制程序流程,利用異常做數(shù)字的判斷函數(shù),利用異常消除系統(tǒng)中可能出現(xiàn)的惱人的異常提示框,為了更好了利用異常看了很多關(guān)于異常的文章,直到有一天
.NET開發(fā)過程中不是程式的無法運行,就是程式的效率慢的同蝸牛在爬; 這種情況在.NET的新手中尤其常見;我不知道為什么,一些介紹.NET開發(fā)的書本里引用的例子代碼,也對此問題視而不見,尤其讓我郁悶的是一些我喜歡的書也出現(xiàn)了同樣的問題。
這篇文章不僅對.NET開發(fā)者的新手有幫助,同樣對哪些有經(jīng)驗,也帶來一些啟示和參考。
他們會遇到什么樣的問題?
1. 數(shù)據(jù)庫連接超時
2. 創(chuàng)建的對象只管用,不管釋放
3. 調(diào)試(Debug)模式下編譯后,就用于應(yīng)用環(huán)境中了
4. 實際作業(yè)模式分享
上面的問題就像毒瘤,積累到一定程度就爆發(fā),且影響深遠。
1.數(shù)據(jù)庫連接超時篇
若要知道數(shù)據(jù)庫連接超時問題,先看下面一段代碼:
[sample-01]
| 以下為引用的內(nèi)容: Public Shared Function getOEMPN(ByVal psPN As String, ByRef OEMPN As String) As BSResult |
對上述代碼行的部分解釋:
Dim clsOraDb As New clsOraClienDb:引用數(shù)據(jù)庫連接的類;
clsOraDb.Open(strConn):打開數(shù)據(jù)庫連接;
然后,整個函數(shù)你再找不到關(guān)閉數(shù)據(jù)庫連接的動作,是要等著操作系統(tǒng)來釋放嗎? 有人就說啦,看起來好像沒有什么大不了的,這僅僅是一個函數(shù)而已;數(shù)據(jù)庫打開連接,未關(guān)閉不會影響到整個應(yīng)用程式;果真是這樣嗎?
讓我們談?wù)剶?shù)據(jù)庫連接的問題,在Oracle數(shù)據(jù)庫里,一般默認的數(shù)據(jù)庫連接數(shù)最多也就100多來個,不會超過200個,即使你改變這個連接數(shù);但無論怎樣,它的連接數(shù)是有限的;不可能無限地供你消耗。
在Web這個程式里,它不僅不會自動關(guān)閉數(shù)據(jù)庫連接,象這樣的函數(shù)還會每次調(diào)用,都會重新用掉一個數(shù)據(jù)庫連接;如果象這樣的函數(shù)很多的話,你就等著一個錯誤警告頁面彈出來,如Database Connection Timeout…等訊息。
這還不算什么,更有甚者,盡然在循環(huán)語句里寫下面的代碼如 :
[sample-02]
| 以下為引用的內(nèi)容: Foreach(DataRow row in tabl.select(“”,”ProductID”) |
說到這,有人就問啦;我在開發(fā)環(huán)境下測試一點問題都沒有呀?是呀,你是沒有問題;我想問的是,你開發(fā)環(huán)境的測試數(shù)據(jù)有幾筆?
現(xiàn)在,問題已經(jīng)知道在哪里,怎么解決?
針對[sample-01]做如下處理,注意下面代碼:
| 以下為引用的內(nèi)容: Public Shared Function getOEMPN(ByVal psPN As String, ByRef OEMPN As String) As BSResult ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString |
注意上面的兩句代碼:clsOraDb.Close和clsOraDb.Close;
在異常處理的時候,特別提醒兩點:
(1)你的數(shù)據(jù)庫關(guān)閉的時候應(yīng)該是在代碼行0028前,而不是后;
(2)有人不習慣(或者一時疏忽)加上0088行的代碼;
針對[Sample-02]和[sample-03],把打開數(shù)據(jù)庫連接寫在所有的循環(huán)語句之前,如:
| 以下為引用的內(nèi)容: clsOraDb.Open(strConn) |
當然還有另外一個做法,就是用Using語句,提交.NET應(yīng)用的垃圾收集器自動收集;相關(guān)的文章很多;這里不再特別贅述。
2.對象只管創(chuàng)建應(yīng)用,不管釋放篇
我們繼續(xù)用[Sample-01]的代碼:
Dim dtResult As New DataTable
誰會發(fā)現(xiàn)它被釋放,你不能,我也不能,從來沒有被釋放過。
“Dim dtResult As New DataTable”行的代碼解釋是,要在內(nèi)存劃分一個空間給這個定義的對象dtresult;系統(tǒng)要劃分多大的空間呢?呀,我沒有研究過(留給那些有心人吧,呵呵。.);但有一點,要在內(nèi)存劃分一個空間,就是要占用內(nèi)存;那么內(nèi)存有多大呢,不是無限大吧;也是有限的;所有運行上述代碼的最終結(jié)果是,系統(tǒng)的執(zhí)行效率越來越慢;有人就懷疑,我有內(nèi)存1到2G的,加上虛擬內(nèi)存就更大;我只能說你的懷疑沒錯;可是你的應(yīng)用程序就用這么一只函數(shù)嗎?我想肯定不是;所以上百只函數(shù)的應(yīng)用執(zhí)行對內(nèi)存的消耗可想而知;如果是后臺自動運行的程序,及時是一個function,也會讓系統(tǒng)崩潰;這只是一個簡單的例子,有更復雜的;象這樣的對象應(yīng)用還有:Dataset, Datatable,DataReader,DataAdapter,Datagrid.。等;
那么怎么解決這些問題呢?
(1)在Try catch 語句前定義好所用的對象; 如:
| 以下為引用的內(nèi)容: Dim dtResult As New DataTable |
(2)釋放的語句如下:
| 以下為引用的內(nèi)容: Dim dtResult As New DataTable |
有人習慣寫成下面這樣:
| 以下為引用的內(nèi)容: Dim dtResult As New DataTable |
這不是也釋放了嗎?我想問的是,如果程序出現(xiàn)異常,它們會釋放嗎?我肯定得告訴大家,它們一定不能釋放。為了確保程序的穩(wěn)定運行,我建議大家都來用Try Catch語句。
(3)絕不建議在循環(huán)語句寫如下的語句:
| 以下為引用的內(nèi)容: Foreach (DataRow row in tabl.select(“”,”ProductID”) |
正確的寫法是:
| 以下為引用的內(nèi)容: Dim DS new Dataset |
另外,提醒大家一點,記得用 For Each 語句替代For i=0 to Rowcount-1;這樣的效率改善也是明顯的;
3.調(diào)試(Debug)模式下編譯就用于應(yīng)用環(huán)境中篇
大家看下面的圖片:

有人會留意這個界面嗎?有,但一定不多。
接著,程式開發(fā)好(也包括單元測試),然后編譯直接分發(fā)到應(yīng)用環(huán)境。
整個過程就結(jié)束了;誰也不曾想,這里埋下了一個深深的地雷;據(jù)微軟的人講,這樣分發(fā)的程式到應(yīng)用環(huán)境,你有多少內(nèi)存恐怕都不夠,所以微軟建議我們做如下的工作:
“ 主站蜘蛛池模板: 西畴县| 内乡县| 辉南县| 五常市| 应用必备| 沁水县| 沁水县| 封开县| 清河县| 高邑县| 滨州市| 舒兰市| 高唐县| 遂昌县| 凉城县| 渭源县| 锡林郭勒盟| 合肥市| 隆德县| 尼玛县| 上林县| 绵阳市| 横峰县| 张北县| 石棉县| 鄱阳县| 沅陵县| 元朗区| 独山县| 土默特左旗| 河北省| 乐陵市| 黔江区| 三台县| 娄底市| 肃南| 株洲县| 泗水县| 隆昌县| 重庆市| 班戈县|