Cannot access a disposed object in ASP.NET Core

楠木大叔    

导航

  • 常见原因
  • 总结

  对于.neter来说,在使用ASP.NET Core的过程中,大家或多或少会遇到这样的报错——“Cannot access a disposed object”。出现这样的异常的原因有很多,如果它在调试的时候出现是很容易解决的,但是有些时候它在本地运行良好,等到你部署到生产环境才会表现出来。针对这个异常,请跟随我一起来分析和探究其根本原因。

  在ASP.NET Core开发中,我多次碰见了这样的报错,并且跟踪这个bug很艰难。这样的报错有多种原因。有时仅凭其表现的“症状”就能修复这个Bug,但是有时候又极其痛苦。通过寻找“病因”,我们可以反过来优化自己的代码。

  错误信息很清楚:

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.

Object name: 'XXXContext'.

常见原因

对象已经释放(The object is disposed in your code)

  最简单的原因是你有一个可以释放的对象,然后你在代码的某个地方释放了它。也可能是你释放了一个使用了该对象的对象。当你试图访问一个被释放的对象时,就引发了该异常。此时,你要做的就是查看该范围的代码路径,或者上下文调用关系,通过打断点来排查该问题。

代码异步执行(Some code is running async)

  我遇到的另外一种原因是你在新线程中执行了某段逻辑。依赖的框架释放了对象,并将该对象返回给主线程。

新的线程执行了已经释放的对象,然后引发异常。要解决此问题.你必须单独地开启新线程来管理这个可以被释放的对象。

Task.Run( () => { // or ThreadPool.QueueUserWorkItem(async _ => {
using (var context = **create your new context here, handle it directly or let the DI framework do its magic**){
foreach(var user in Users){
email.Send(user.email);
context.....;
context.SaveChanges();
}
}
});

  在APS.NET Core Web API 中,我们可以用Swashbuckle.AspNetCoreNSwag这两个包来实现Swagger,而且二者都是github上开源的。此外,nswag还提供了生成typescript客户端代码的方法以及用于API的服务代码。

使用async void 而非 async Task

  另一种原因可能是你在本应该使用使用async Task的地方使用了async void。潜在的异步代码会在你的线程返回之后执行。就像在代码中启动一个新线程一样,它可能会意外地正确运行。在这种情况下,您可能只在release版本中看到错误。当您不知道在哪里查找时,这可能很难调试。PS:笔者恰好遭遇该情况,我和我的小伙伴花费了一天时间来找这个bug。

   错误的写法:

public async void FailtyMethod(){

   正确的写法:


public async Task CorrectMethod(){

总结

  解决这些bug,有时候会令人沮丧,甚至抓狂。我曾今和我的另外两个小伙伴花费了一天时间来找这个bug。最后大家都黔驴技穷。

  我希望这篇文章能够帮助到你。

参考

关注

  请关注微信公众号智客坊

Cannot access a disposed object in ASP.NET Core的更多相关文章

  1. asp.net Core HttpClient 出现Cannot access a disposed object. Object name: 'SocketsHttpHandler' 的问题。

    ASP.NET Core 部署在Centos 中 偶尔出现 One or more errors occurred. (Cannot access a disposed object.Object n ...

  2. Xamarin.Forms bug? System.ObjectDisposedException: Cannot access a disposed object

    Hi, My Android Xamarin.Forms application uses a Navigation stack to display various views, I often h ...

  3. System.Net.Sockets.Socket SendAsync System.ObjectDisposedException: Cannot access a disposed object.

    发生未处理的域异常! System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net ...

  4. abp Cannot access a disposed object. A common cause of this error is disposing

    框架:abp 异常信息: An unhandled exception was thrown by the application.System.ObjectDisposedException: Ca ...

  5. # - net - cannot access a disposed object r nobject name filebufferingreadstream

    .Net Core 2.1-Cannot access a disposed object.Object name: 'IServiceProvider' (3) I just migrated .N ...

  6. ASP.NET Core 问题排查:Request.EnableRewind 后第一次读取不到 Request.Body

    实际应用场景是将用户上传的文件依次保存到阿里云 OSS 与腾讯云 COS ,实现方式是在启用 Request.EnableRewind() 的情况下通过 Request.Body 读取流,并依次通过 ...

  7. ASP.NET Core 新建线程中使用依赖注入的问题

    问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 . TCPService 通过构造函数注入了 ContentService , ContentService ...

  8. 解决ASP.NET Core在Task中使用IServiceProvider的问题

    前言 问题的起因是在帮同事解决遇到的一个问题,他的本意是在EF Core中为了解决避免多个线程使用同一个DbContext实例的问题.但是由于对Microsoft.Extensions.Depende ...

  9. asp.net core mvc 在中间件中使用依赖注入问题:System.InvalidOperationException: Cannot resolve scoped service 'IXXXService' from root provider.

    今天在弄JWT的时候需要用到用户验证使用一个自己写好的验证,但在出现了:System.InvalidOperationException: Cannot resolve scoped service ...

随机推荐

  1. 虚IP解决AlWaysON读库服务器过保替换

    公司核心交易数据库,使用SQL 2012 AlWaysON的1主4从,有2台(8.14,8.15)从库服务器,已经使用3年多,过保替换,新买的2台服务器已经安装好,一开始方案如下: 服务器(8.14) ...

  2. windows系统下安装JDK8

    学习JAVA,必须得安装一下JDK(java development kit java开发工具包),配置一下环境就可以学习JAVA了,下面是下载和安装JDK的教程: 一.下载 1.JDK下载地址: h ...

  3. Protostuff序列化问题

    最近在开发中遇到一个Protostuff序列化问题,在这记录一下问题的根源:分析一下Protostuff序列化和反序列化原理:以及怎么样避免改bug. 1. 问题描述 有一个push业务用到了mq,m ...

  4. 行数据库VS列数据库

    一.介绍 目前大数据存储有两种方案可供选择:行存储和列存储.业界对两种存储方案有很多争持,集中焦点是:谁能够更有效地处理海量数据,且兼顾安全.可靠.完整性.从目前发展情况看,关系数据库已经不适应这种巨 ...

  5. JAVA测试(选择题)

    1.分析如下所示的Java代码,其中this关键字的意思是(  ) Public class Test { Private String name; Public String getName(){ ...

  6. Guava的RateLimiter实现接口限流

    最近开发需求中有需要对后台接口进行限流处理,整理了一下基本使用方法. 首先添加guava依赖: <dependency> <groupId>com.google.guava&l ...

  7. 基于redis(订阅发布)实现python和java进程间通信

    主要结构为: python进程发布消息,java进程订阅消息. 依赖环境: python:   pip install redis java:  jedis 1. python端: PubSub.py ...

  8. 在命令行已经pip install flask-script,但是导包时出错

    问题:(已经安装好了flask-script,但是导入不成功) 然后在代码中导入相应的包:(报红) 后来发现是在自己创建项目的时候勾选的是创建的是在虚拟环境下的项目,所以环境有问题 所以我应该在虚拟环 ...

  9. SQLServer的网络协议

    一.总结 1.SQL Server访问协议包括Shared Memory.Named Pipes.TCP/IP.VIA四种,多数应用系统都是通过TCP/IP协议访问数据库.安装数据库后需要启用TCP/ ...

  10. mybatis #号与$号的区别

    区别: 在sql中当传入的参数是字符型,则用#号会带上单引号,不会引起sql注入: 在sql中当传入的参数是字符型,则用$号不会带上单引号,会引起sql注入: 使用范围: 当传入的参数用于查询条件,尽 ...