都知道發燒不是因為額頭被熱水燙過,肚子疼通常也不會是因為肚子受傷.其實調程式也是如此.
找錯誤的時候不該隻從錯誤的地方區找,有可能在遙遠的地方的問題,導緻了這裡的錯誤.
也不要去相信那些從來沒出過錯的地方,就是不會錯的,從來不錯隻表示它過去沒錯,不表示現在也是對的.
今天一個同僚的程式就遇到這個問題,一個自定義表格控件,用了很久了,突然今天發現在一個窗體上操作着操作着就綁不出來資料.
重新進入窗體又可以了,郁悶了很久,單步調試了幾個小時(因為不知道怎麼重制這個錯誤,反正就是"某些操作"以後會錯),把所有的
代碼邏輯都過了好多次,可是就是找不出錯在哪,隻知道就是在某些地方經過以後,就再也不可能出來資料了.
晚上沒轍了,明天要用的,就這個地方過不去,于是扔給我幫忙. 我重複操作幾次,掌握到大緻的出錯地方,然後就在重點區域,如綁定操作
的附近設了斷點,運作了幾次次,發現代碼沒有錯,sql語句傳回正确,表格綁定方法也沒有問題,傳回true,就是資料再也不出來.
觀察到表格的腳部對資料的條數統計是正确的,隻是上面不顯示資料. 監視了表格控件的一些主要的屬性,意外地發現,表格中表示
目前頁索引的屬性值是-1,顯然這是問題所在,搜尋了一下,發現窗體中沒有對這個屬性指派的操作.那-1又是怎麼來的? 重新進入窗體
屬性值出現正确的0,然後做會改變這個值的操作(翻頁,在表格元件内部實作) 發現都正常,然後再嘗試那些有可能産生錯誤的操作,
試了好幾次,終于有一個地方,操作以後變成了-1,-1以後就永遠-1了. 當一個操作導緻表格中沒有資料的時候,表格的頁索引就變成-1
腦海中馬上明白發生了什麼事了,bug在表格控件内部. 馬上也猜出産生這個錯誤的原因. 原來表格本身保持了這個屬性的狀态,這樣
在多次綁定資料的時候,如果第一次綁定了n頁,第二次綁定了m頁(n>m+1),并且在第一次綁定以後,翻到了第p頁(n>p>m),那麼在第2次
綁定的時候這個狀态依然是p,而實際上資料卻并沒有那麼多,會抛出nullreferenceexception的異常,于是猜測表格控件的設計者考慮到這個情況,
于是,對此做了處理,當遇到這個情況時強制令 p=m-1 (因為一個索引是0開始,一個是1開始,是以-1). 但是他卻忽略了同時m=0的情況.
在m=0的時候,p就出現了-1 .由于這個第-1頁是沒有意義的,也是原控件設計者所沒有考慮到的情況. 就發生了上述那些奇怪的總數
統計正常,而資料不顯示(因為根本不存在第-1頁的資料),由于上面沒有資料,又引起了翻頁功能的不可用,是以也不可能把這個-1
給修改回來,于是就不管怎麼綁資料,怎麼操作,都一直-1下去了...
反編譯了原控件,從il中證明了我的猜測完全和實際情況一緻. 于是解決問題就變成非常簡單了.
另外有一點,控件中對一些異常,有必要throw出來給外面一層,雖然說如果外面沒有處理會造成程式崩潰,但是要是把所有沒有意料到
的異常都用一個空的catch塊把它殺死在控件内部,其實更加危險,造成程式的不可預料性,而且又難以查找.是以這裡有一個平衡的問題.
這還是看設計者的經驗,具體問題具體分析.