記一次EF Core DBContext在Action委托中GC異常的問題.

来源:https://www.cnblogs.com/lmy5215006/archive/2019/10/24/11735295.html
-Advertisement-
Play Games

今天在開發過程中發現.在SaveChanges的時候偶爾會拋出異常:Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependen ...


今天在開發過程中發現.在SaveChanges的時候偶爾會拋出異常:Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

異常說得很明顯,通過依賴註入的DBContext上下文已經被其他地方Dispose了.所以無法再次Dispose.

 

 

 

 

 

 

代碼邏輯很簡單,就是發送郵件後,調用委托通知tracking發送成功.然後保存到資料庫.

按理說這段代碼沒問題,但就是報錯了.

一開始以為是哪裡沒有await,所以導致task開的新線程沒有被等待,從而導致提前gc.但代碼就這麼多,都檢查過了沒有遺漏的地方.排除

後來懷疑是DBContext的生命周期問題,但DBcontext是ServiceLifetime.Scoped.  同一個request中是單例的.排除

後來經過和同事交流,在代碼結尾處加入Task.CompletedTask.等待所有線程結束.

 

神奇的事情發生了,完美運行.不報錯了.

那這樣的話,就問題就只可能是定義的Action<int> rollBack委托的問題了.

 

 

 

 

 

 猛然發現,儘管我在代碼中確實加入了async/await關鍵字

 

 

 但是這裡的非同步等待,只是非同步等待委托內部的操作.並不等待Action委托本身.也就是說,當我們執行委托里的方法時.開闢了一個新的線程去執行_dbContext.SaveChangesAsync()的方法.但是並沒有等待它完成.

這時候主線程會立即執行下一步,也就是返回結果給Controller層.  Return Ok()給前端.這個時候DBContex立刻就會調用Dispose.等到委托的方法調用完畢再次Dispose的時候.自然而然的就會拋出異常啦.因為他之前已經被Dispose了.

所有解決辦法很簡單

方法一 在代碼結尾加入await Task.CompletedTask  等待所有線程都結束.再返回.

方法二 講Action<int> 換成 Func<int,Task> 併在調用委托前 await 

 

經過這次問題,還是暴露出不少問題.

1:對async/await 還是有認識不足的地方.基礎知識不扎實,導致了對委托的錯誤使用.

2:對自己的代碼太過自信.沒有做完整的測試.事實上 這裡的代碼我都沒測試過就上了DEV環境.認為很簡單不會出問題的.做事還是太浮躁.

所以寫一篇博客,用以自省

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 恢復內容開始 需要安裝三個庫(requests,BeautifulSoup4,lxml) pip install requests BeautifulSoup4 lxml 彈幕消息會滾動在終端上 且會在當前目錄下生成以主播名字命名的文件 恢復內容結束 ...
  • 1 背景 像我們去面試一些大公司的時候,就會遇到一些關於緩存的問題。可能很多同學都是接觸過,多多少少瞭解一些,但是如果沒有好好記錄這些內容,不熟練精通的話,在真正面試的時候,就很難答出來了。 在我們的平常的項目中多多少少都會使用到緩存,因為一些數據我們沒有必要每次查詢的時候都去查詢到資料庫。 特別是 ...
  • 前言 Redis哨兵模式,用現在流行的話可以說就是一個“哨兵機器人”,給“哨兵機器人”進行相應的配置之後,這個"機器人"可以7*24小時工作,它能能夠自動幫助你做一些事情,如監控,提醒,自動處理故障等。 Redis-sentinel簡介 Redis-sentinel是Redis的作者antirez, ...
  • Spring註解之@Conditional 【1】@Conditional介紹 ​ @Conditional是Spring4新提供的註解,它的作用是按照一定的條件進行判斷,滿足條件給容器註冊bean。 ​ @Conditional源碼: ​ 從代碼中可以看到,需要傳入一個Class數組,並且需要繼承 ...
  • 一.open文件讀取 1.open('file','mode')打開一個文件 file 要打開的文件名,需加路徑(除非是在當前目錄) mode 文件打開的模式 需要手動關閉close 2.with open('file','mode')as... 不需要手動關閉文件 3.'r': 以只讀模式打開(默 ...
  • 恢復內容開始 最近各大一二線城市的房租都有上漲,究竟整體上漲到什麼程度呢?我們也不得而知,於是乎筆者為了一探究竟,便用 Python 爬取了房某下的深圳租房數據。以下是本次的樣本數據: 除去【不限】的數據(因為可能會與後面重疊),總數據量為 16971 ,其中後半部分地區數據量偏少,是由於該區房源確 ...
  • 為什麼需要新的JSON API? 為什麼需要新的JSON API? JSON.NET 大家都用過,老版本的ASP.NET Core也依賴於JSON.NET。 JSON.NET 大家都用過,老版本的ASP.NET Core也依賴於JSON.NET。 然而這個依賴就會引起一些版本問題:例如ASP.NET ...
  • 博客開通已經7年多了,也沒寫過什麼東西,最近,突然想記錄下自己的軟體開發生涯,於是,找回賬戶,登錄一看,還是當時還是在學校的時候學習的時候記錄過一個sql批量到數據的Demo,近兩年來,微服務架構火起來了,前端VUE、React等框架也變得很流行,在此,利用業餘時間談談我對.netcore微服務架構 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...