記一次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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...