1. 程式人生 > >非同步調用出了個吐血的bug

非同步調用出了個吐血的bug

        非同步呼叫就是啟動了新的執行緒,主執行緒與方法執行緒並行執行,一個可以無需等待被呼叫函式的返回值就讓操作繼續進行的方法,非同步呼叫節約了大量的等待時間,客戶體驗感直線上升,但是非同步呼叫也有令人頭疼的時候,分享一個我最近遇到的問題。

        背景:C#開發,客戶要求增加檔案批量修改功能,模式為在目錄上選中需要維護的資料後點擊維護按鈕彈出變更表,將目錄資料帶入變更表,在變更表上修改需要維護的資料再儲存,儲存後將變更表頁面關閉然後開啟審批表,將變更後的資料項儲存到審批表中進行審批。

        問題:在碼程式碼時為了提高速度,變更表close()方法(關閉事件)與審批表openPage()事件用非同步呼叫處理,都是在變更表點選onSave()事件後觸發。寫好後本地測試時毫無問題、一切正常,然後丟到測試伺服器,測試工程師測試也是毫無問題就升級到正式伺服器上去了,然後問題就出現了。偶爾出現"未將物件引用設定到物件的例項",空引用了,而且不經常出現,客戶反饋過來後我們測試伺服器多次測試也有這樣情況出現,最尷尬的就是本地斷點除錯怎麼也不能復現問題,異常不復現就沒辦法解決啊,拿到log日誌後看到是審批表openPage()後校驗單據型別以及時間戳時單據型別和時間戳都是空值,按道理講不會出現空值,都是單據載入後這些資料就load上了。

        處理:一時間找不到問題癥結,本地測試確實單據開啟後資料項就load上了,就請教了下師傅,師傅看了一遍在經驗之上就確定是非同步調用出的問題,非同步呼叫關閉事件執行將資料項全部置為null,所以單據開啟之後進行校驗就出現空引用了,非同步呼叫時間執行快慢導致了bug會ouer出現,本地斷點一定不會復現問題,斷點的時間程式早就執行過去了。最後將close()事件裡面的置null方法前加了個:Thread.Sleep(1000);問題得以解決。        https://mp.weixin.qq.com/s/cs_2wPiSN3eog-Qt7wvxjQ