EntityFramework中的線程安全,又是Dictionary


繼上次記一次w3wp占用CPU過高的解決過程(Dictionary和線程安全)后又再次與Dictionary博弈,這一次是在EntityFramework中的Dictionary。

從一個異常說起

image

這個異常與上次的異常有着同一個特性:間歇性,碰到類似的異常在信心上就被削弱了一大半。。。

在第一次看到這個異常的時候覺得解決它非常的簡單,無非就是在字典操作的地方加個鎖,但仔細看了一會發現這個問題並沒有那么簡單,可以看到這個異常的最后幾個堆棧信息來自System.Data.Entity命名空間,也就是EntityFramework,這就使問題變得難以尋糾。

image

出錯的地方就在FirstOrDefault,一個在簡單不過的Linq方法。

反編譯查看EntityFramework的實現

AddNewRelation方法的內容如下:

image

馬上鎖定了AddRelationshipEntryToDictionary,方法代碼如下:

image

可以看出是EntityFramework添加狀態監控相關的邏輯,看到這也大概猜出來了又是線程安全的問題,但為了確定我追糾了調用AddNewRelation的HandleRelationshipSpan方法。

image

代碼比較復雜,較難看懂,於是就去EntityFramework源碼托管的站上面去看看是否有寫注釋,碰碰運氣。

果不其然還是存在比較詳盡的注釋

image

問題也大致清晰了,應該是線程共享的DbContext出現了問題。

用Demo還原異常

image

image

解決方案

因為我們並不想放棄線程內共享一個DbContext的方案,所以我們並沒有從根本解決這個問題,我們把調用FirstOrDefault的操作放在了Lazy里面。

image

剩下的就是觀察效果。

寫在最后

寫了兩篇解決BUG的紀要不為了大家能快速解決問題,而為了交流一種尋找BUG解決BUG的思路與方法。

最后,福州地區有需要找工作或者想換工作的“猿”嗎?如果有可以溝通溝通聯系聯系唄。


免責聲明!

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



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