ASP.NET Core 新建线程中使用依赖注入的问题
2018-07-23 11:46
1201 查看
问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 。
TCPService 通过构造函数注入了 ContentService , ContentService 的实例依赖了 AppDbContext (继承自 EF Core 的 DbContext)。在 TCPService 中通过 Thread.Start 启动了一个新的线程执行了 TCPService 中的 Receive 方法,在 Receive 方法中通过 ContentService 进行保存数据库的操作,而在访问 AppDbContext 的实例时出现对象已被 Disposed 的错误。
Object name: 'AppDbContext'. --->System.ObjectDisposedException: 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.
针对这个问题,尝试改为通过构造函数注入 IServiceProvider ,在 TCPService.Receive (在新线程中执行的方法)中通过 IServiceScope 解析
using (var scope = _serviceProvider.CreateScope()) { var contentService = scope.ServiceProvider.GetRequiredService<ContentService>(); //... }
结果发现 IServiceProvider 也被 Disposed
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'IServiceProvider'.
由此可以推断在 ASP.NET Core 中在新建的线程中无法通过依赖注入的方式访问实现了 IDisposable 接口的对象(单例对象除外,但实现 IDisposable 接口的类型通常不会注册为单例),也就是只要请求一结束,实现 IDisposable 接口的对象的 Dispose 方法就会被调用。
那如何解决这个问题呢?
1)最下下策的解决方法是将 DbContext 注册为单例
services.AddDbContext<AppDbContext>(options => { }, ServiceLifetime.Singleton);
它会带来很多副作用,不考虑。
2)在保存数据至数据库的实现方法中基于 DbContextOptions (它是单例)手工 new AppDbContext ,用这个 DbContext 实例进行保存操作。
public class ContentService : Repository<Content> { private readonly DbContextOptions _options; public ContentService(AppDbContext Context, DbContextOptions options) : base(Context) { _options = options; } public override async Task<bool> SaveAsync(Content entity) { using (var context = new AppDbContext(_options)) { context.Set<Content>().Add(entity); return await context.SaveChangesAsync() > 0; } } }
实测有效。
相关文章推荐
- ASP.NET Core中使用GraphQL - 第三章 依赖注入
- asp.net core mvc 在中间件中使用依赖注入问题:System.InvalidOperationException: Cannot resolve scoped service 'IXXXService' from root provider.
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(六)-- 依赖注入
- asp.net core-9.依赖注入的使用
- ASP.NET Core依赖注入解读&使用Autofac替代实现
- [转]使用依赖关系注入在 ASP.NET Core 中编写干净代码
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
- ASP.NET - 使用依赖关系注入在 ASP.NET Core 中编写干净代码
- asp.net core 依赖注入问题
- ASP.NET Core依赖注入解读&使用Autofac替代实现
- ASP.NET Core依赖注入解读&使用Autofac替代实现
- ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便
- 使用依赖关系注入在 ASP.NET Core 中编写干净代码
- ASP.NET_MVC使用Spring.Net.MVC依赖注入学习笔记
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【四】——实现模型工厂,依赖注入以及格式配置
- 使用Autofac在ASP.NET Web API上实现依赖注入
- Asp.net MVC 中使用 Ninject 实现依赖注入
- ASP.NET Core 1.0基础之依赖注入
- 在ASP.NET MVC中使用Unity进行依赖注入的三种方式
- 在ASP.NET MVC中使用Unity进行依赖注入的三种方式