记一次EF Core DBContext在Action委托中GC异常的问题.
今天在开发过程中发现.在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环境.认为很简单不会出问题的.做事还是太浮躁.
所以写一篇博客,用以自省
记一次EF Core DBContext在Action委托中GC异常的问题.的更多相关文章
- EF Core使用CodeFirst在MySql中创建新数据库以及已有的Mysql数据库如何使用DB First生成域模型
官方教程:https://docs.microsoft.com/en-us/aspnet/core/data/?view=aspnetcore-2.1 使用EF CodeFirst在MySql中创建新 ...
- [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- EF Core in Action 中文翻译 第一部分导航
Entityframework Core in action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Core ...
- [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 2.0] 查询数据库
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.9] 掀开EF Core的引擎盖看看EF Core内部是如何工作的
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.8] MyFirstEfCoreApp应用程序设置
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译 EF Core in Action 1.7] MyFirstEfCoreApp访问的数据库
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- [翻译] EF Core in Action 关于这本书
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
随机推荐
- Visual Studio Code安装以及C/C++运行环境搭建
众所周知VSCode是全宇宙最好用的编辑器 (雾 配置了很久,今日终于配置完成了,还是有点麻烦的,本文是为了方便一些不懂怎么配置的小白,以及还有一些美化教程. 一.安装 Visual Studio C ...
- mysql 函数 存取过程
1.打开数据库 2.选择函数,点击新建函数,选择过程,点击完成 4.写入自己要添加的sql语句 5.点击CTAL + S 保存,如若报错则语法或函数错误
- 一步步构建.NET Core Web应用程序---仓储层,业务层的实现
前言 上一篇文章介绍了整个项目的结构,接下来向大家介绍一下 我的 仓储及业务层具体的实现思路,如果有更好的实现方式,希望大家及时指出!!! 构建过程 一,数据访问 首先在 DataProvider 中 ...
- 快速入门和使用HTML–使用Django建立你的第一个网站
一 前记 你每天浏览的网页,通过网络看的新闻,看着淘宝京东的绚丽多彩的界面.是否想过这个问题,它是怎么实现的呢?有没有搜过相关的知识呢?假如没有,假如你是一位对事物好奇的主或者是做计算机相关东西的人. ...
- 从壹开始学习NetCore 45 ║ 终于解决了事务问题
一.项目说明 哈喽,又来写文章了,原来放假可以这么爽,可以学习和分享,
- Spring框架(三)
对象依赖关系 Spring中,如何给对象的属性赋值? [DI, 依赖注入] 1) 通过构造函数 2) 通过set方法给属性注入值 3) p名称空间 4)自动装配(了解) 5) 注解 代码示例: &l ...
- react redux 二次开发流程
在一个大项目中如何引入redux及其相关技术栈(react-redux redux-thunk redux-immutable ),已经成为react前端工程师不可或缺的技能,下面通过实现一个简单的t ...
- uC/OS-III 软件定时器(三)
软件定时器是uC/OS 操作系统的一个内核对象,软件定时器是基于时钟节拍和系统管理创建的软件性定时器,理论上可以创建无限多个,操作简单,但精准度肯定比硬件定时稍逊一筹. 原理和实现过程 要用到的函数: ...
- php7和php5区别是什么
PHP7距正式发布以及有挺长时间了,刚出道就号称比旧版本快了几倍,各种开源框架或系统运行在PHP7上速度效率提高了几倍.那么php7和php5之间的区别是什么?下面本篇文章就来给大家简单介绍一下,希望 ...
- MongoDB 学习笔记之 mongo-connector安装
mongo-connector安装: https://github.com/mongodb-labs/mongo-connector 1. yum -y install openssl* 2.编译安装 ...