目 錄
1. 現象概述... 1
2. 操作數據庫的代碼... 2
3. 引起的異常... 2
4. 異常信息分析... 3
5. 分析結論猜測... 3
1. 現象概述
.NETCore的Console和AspNetCore程序對數據庫進行操作,通過析構函數(Finalize)釋放數據庫連接資源,在Linux平台引起程序或服務異常退出,在Windows平台沒有出現。
2. 操作數據庫的代碼
析構函數(Finalize)釋放數據庫連接的代碼,如下:
/// <summary> /// 析構函數,釋放數據庫連接資源 /// </summary> ~ServesDBContext() { Dispose(); System.Diagnostics.Debug.WriteLine("ServesDBContext 回收了!"); } /// <summary> /// 釋放數據庫連接資源 /// </summary> public void Dispose() { if (Context != null) { Context.Dispose(); } }
3. 引起的異常
Console控制台程序,實時運行的服務運行一段時間就會出現異常信息:Object reference not set to an instance of an object。如下圖:
AspNetCore應用程序,除了提示上述信息以外,還打印出來的異常信息::system.threading.lockrecursionexception: recursive write lock acquisitions not allowed in this mode。如下圖:
4. 異常信息分析
首先異常信息的Exception已經捕捉到了,但是運行的程序異常退出了(Abort)。查找官方的文檔,按關鍵lockrecursionexception搜索,網址:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.lockrecursionexception?view=netcore-3.1。關鍵提示信息,如下圖:
MSDN關鍵提示信息:程序使用無參數構造函數創建一個 ReaderWriterLockSlim,該構造函數不允許使用遞歸。
5. 分析結論猜測
第一層猜測:是由於析構函數釋放資源引起了程序出現遞歸現象(recursion)。
第二層猜測:析構函數釋放資源出現遞歸現象,可能是由於Linux的垃圾回收機制與Windows的垃圾回收機制不同引起的,因為同樣的代碼,在Windows下沒有出現任何問題,但是Linux下沒有更深入的研究。
第三層猜測:類同樣繼承了IDisposable資源釋放接口,實現了Dispose函數。同時又實現了析構函數(Finalize)釋放資源,同樣調用了Dispose函數。兩種釋放資源,在Linux下垃圾回收過程造成了沖突。
注:由於沒有進一步深入研究,所以以上是針對結論的一種猜測,有感興趣的朋友可以共同研究。
文章:
《.NET Core開發的iNeuOS工業互聯網平台,發布 iNeuDA 數據分析展示組件,快捷開發圖形報表和數據大屏》
《[視頻演示].NET Core開發的iNeuOS物聯網平台,實現從設備&PLC、雲平台、移動APP數據鏈路閉環 》
《.NET Core開發的iNeuOS物聯網平台部署樹霉派(raspbian),從網關到雲端整體解決方案》
《.NET Core開發的iNeuOS物聯網平台部署在Ubuntu操作系統,無縫跨平台》
《iNeuOS 物聯網雲操作系統2.0發布,集成設備容器、視圖建模、機器學習三大模塊 》
物聯網&大數據技術 QQ群:54256083
物聯網&大數據合作 QQ群:727664080
聯系QQ:504547114
合作微信:wxzz0151
界面如下圖: