摘要:SqlDataReader和SqlConnection的使用小問題和程式心得分享
忙了幾天終於把程式寫好
就整理一下,上來記錄也順道分享一下,這次的東西就是--簡易的監控程式,要加到排程裡面。
之所以要寫是因為公司有個地方是上傳電子發票用的 (現在正要慢慢取代紙本),那正常來講之後要上傳到政府那邊,所以必須確認,發票是否有正常的傳送。
因此就要寫隻Batch去監控會比較方便,那當然還要附加預防機制 ( Log紀錄,寄信<搭配DB>)。
一開始寫的時候,懶的畫流程圖,想說很簡易 (程式功能沒幾個),結果寫下去才知道會一直打結 (要Catch 每個 Error,而且不能用大的直接全包)
最後還是屈服稍為畫了一下 (以後一定會畫,省麻煩)。
大致上分為四塊--- Log (Log檔案存取)、Monitor (監控行為的條件)、DataBase(Table存取)、Mail(寄信);此外有些參數寫成Config,提高彈性及安全性
我把前三個寫在同一個Class;後者寫另外一個Class
順序大概如下…
(1) 先確認Log檔位置和相關設定 (和主程式同一個位置,按規定建了二層資料夾)
(2) 從組態檔取得監控所需參數 (Log開始紀錄過程)
(3) 開始監控 (錯誤訊息抓下來)
(4) 回報(將錯誤透過Email,並將Email訊息存入DB以防SMTP主機掛掉,之前所偵錯的資訊無法寄出)
(5) 結束程式
整個程式最麻煩的就是try catch(),由於是巢狀,而且是從四面八方丟過來,要儘可能的把錯誤都Catch下來避免死當,又要能夠精確的寫出是哪個
地方出問題,讓維護人員能夠快速的將錯誤修正。
我用了些小技巧讓程式儘量達到這理想的說法。
將程式依照功能做分堆後 大概就像 { [A,B,C] F [D,E (G) ] } <用不同的括號代表不同層的try catch,這只是概述一下樣子>
每個 functionn裡面大多數都用throw 的方式,將例外狀況往上層拋回,由上層統一去寫入log,在發信時訊息也更能簡單明瞭。
但是就要有耐心點,去了解每個動作會產生的例外情形,
在這過程中,如果是用ADO.NET的,應該是免不了會用到SqlClient 這個namespace裡面的東西 (SqlConnection, SqlDataReader, SqlCommand....)
這次的程式最大的教訓就在這裡… 希望各位不要跟我一樣白痴白痴,我犯的錯誤就是…
把SqlConnection 放在全域共用,這會發生很嚴重的問題
用的時候想說很方便,然後每個地方用完都想說要想close或dispose掉,怕資源浪費,這想法是對的,但是如果用不對的方式去處理,會害死你。
特別在SqlDataReader這種需要保持在連線狀態下的物件,一旦關閉了連線,就會跑出
讀取器在關閉或開啟時,嘗試讀取MetaData,但是無反應
我Googld半天找不到相關處理,後來慢慢想,才覺得不對勁,SqlDataReader 的迴圈裡,去呼叫了另一個function,結果function把共用連線關了…(我Debug2小時...)
改掉就可以了,但是真的很無言,因為這一個小地方的忽視,造成時間成本上的浪費,真不划算。
後來我都用using () {} 把每個需要做什麼open、close、dispose包起來,微軟是說用完會自己關掉 (聽說不會),但起碼程式是不會有
(不知道誰去關了門) 這個問題存在
以上就是這次程式所學到的分享,接下來要寫測試報告了,禮拜四要release meeting ... 冏