应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

ef core上下文对象在异步情况下被自动释放的问题。Cannot access a disposed object. A common cause of this error is disposing a context that was resolved

15147人阅读 2020/2/28 23:02 总访问:5186169 评论:4 收藏:0 手机
分类: .NET Core

我们看看下面的代码:

这里为了节省效率,更新缓存的操作放到了异步中去执行,但是执行到Article findArticle = _articleDAL.GetAtricleById(id);这一步的时候,ef的上下文对象会被释放掉,调用查询等操作就会报错: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

我对这个原因的理解:

是依赖注入生命周期的问题,scope模式是同一个请求获取得到相同的实例(ef注入的默认方式是scope),然后我又使用task开了一个先线程形成异步,这样就造成请求执行完了对象就已经释放了,然后线程里边缺还去用到了ef的上下文对象,所以得到的就是为空的

对.net core注入模式的了解可以参考:http://www.tnblog.net/aojiancc2/article/details/167

对于默认模式我们在这里也可以看到


想到的解决方法:

方法一:先把需要的数据查询出来然后在使用异步

这样就不怕ef上下文对象被释放了,因为不需要用到了

方法二:我在想既然对象会被释放,那我在异步中重新去依赖注入容器获取一下不就行了

但是这样并不行,要么就是HttpContext对象被释放

那么就是ef上下文对象被释放:

即使你把重新获取的代码放到异步的外面,获取到的ef上下文对象依然是被释放的,因为scope模式是同一个请求获取得到相同的实例,请求完了这个上下文对象就会被释放

方法三:修改ef上下文注入的方式

变成Transient瞬时模式,每次从容器获取都能得到不同的对象

然而还是会被释放,因为我们_articleDAL还是在主线程被创建的,所以_articleDAL下面关联的ef上下文对象也是属于主线程的,主线程执行完了,ef上下文对象依然会被释放

方法四:修改生命周期和重新去依赖注入容器获取结合使用,也就是2,3方法结合一起使用

这样不就可以在异步方法所在线程中维护对象的生命周期么,只要异步所在的线程没有执行完,对象就不会被释放

然而并没有什么卵用还是不行,为什么和想像中的不一样呢。不用异步没有问题,先查询出来在异步更新缓存也没有问题。

但是在异步中去使用ef查询始终有问题呢,难道是因为HttpContext是在主线程中么,所以用它从容器中获取的对象其实还是受主线程的控制,

而且在异步方法中使用HttpContext去获取对象本身就是不科学的。


方法五:更新方法2中的获取依赖注入对象的方式

不去使用HttpContext的方式获取,因为HttpContext本身就属于请求那次的线程

我们使用静态类的方式去获取对象

果然这个问题确实是我们猜想的那样换种获取对象的方法就不会有问题了

net core手动获取依赖注入对象可以参考:

http://www.tnblog.net/aojiancc2/article/details/2980

算了我们绕了这么大一个圈圈其实还是第一种方法最简单,科学


tip:当然你还可以考虑使用单例模式或者AddDbContextPool方式注入,我这里就暂时不尝试了,先弄其他东西了



欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

青春年华

2020/3/3 21:48:19

可以了

青春年华

2020/3/3 21:50:00

厉害啊,不错!

Session

2022/10/24 16:48:05

太赞了,正好碰到这个问题[good]

剑轩:@Session哈哈,看了一下,自己都差点忘记了,以前写过这个,看了一下有一点点印象

2022/10/24 23:49:20 回复

ef core检查某个字段是否是主键,ef不查询更新

使用反射检查ef中某个字段是否是主键,使用如下代码即可//检测当前字段是否是主键 varkeys=userm.Property(item.Name).Met...

ef ef core 使用原生 SQL 查询

有时候在执行一个赋值一点的sql要动态生成用lamdba来写很不方便,新版本用动态生成表达式树的方式也不怎么行了...需要时间...

ef core 公共接口封装

show me code: public interface ICommonDAL<T> where T : class, new() { protected EFContex...

ef core 简介

Entity Framework Core 简介 今天来讲解一下 .NET 中的重要成员 Entity Framework Core。Entity Framework Core (以下简...

ef core异步方式读取与返回数据

我们这里可以使用异步的方式来读取与返回数据publicasyncTask<IActionResult>Index() { returnView(await_context....

ef core 多对多

EF 6.x 支持多对多关系的隐式联接表,但 EF Core 不支持。有关详细信息,请参阅:https://github.com/dotnet/efcore/issues...

ef core创建组合主键

使用modelBuilder.Entity<Type>().HasKey指定多个字段即可protectedoverridevoidOnModelCreating(ModelBuildermodelB...

ef core 预先加载显式加载延迟加载

预先加载读取该实体时,会同时检索相关数据。 此时通常会出现单一联接查询,检索所有必需数据。 可使用 Include 和 ThenInc...

ef core 级联删除

和以前的写法有点不同现在没有modelBuilder.Conventions这种用法了,单独开启级联删除的方法也和以前不太一样以前的写法:p...

ef core SqlSugarFreeSqlDapper EF 对比

EF Core优点:微软官方ORM功能强大,支持模式多文档齐全缺点:1.复杂查询生成的SQL语句性能太差(对操作功力要求高)2.一些...

ef core中使用IDesignTimeDbContextFactory的测试方法,调试方法

DesignTimeDbContextFactory的作用 一些EF Core Tools命令(例如Migrations命令)需要在设计时创建一个派生的DbContext实例...

abp vnext连接mysql。.net core连接mysql。ef core连接mysql

增加一个MySQL的库:Volo.Abp.EntityFrameworkCore.MySQL <PackageReference Include="Volo.Abp.EntityFrameworkCo...

abp vnext ef core连接MySql报空引用错,连接SqlServer报空引用错。abp vnext 的坑

使用abp vnext 真的太喜欢报空引用的错了。你报点错给一点具体的错不行么,这样搞起让人去猜太坑了,比如前面的auto_fac没...

ef core code first 忽略映射数据库字段NotMapped

ef core code first 忽略映射数据库字段非常简单使用NotMapped特性即可。 [NotMapped] public string Status { get; set;...

abp vnext 通用仓储 ef core。WhereIf,多条件,动态条件,分页,动态排序等

abp vnext 通用仓储 ef core WhereIf,多条件,分页等public async Task<List<LandInfoDto>> GetListAsync(Pag...