我可能没想到正确的方向。我是Dependency Injection和ASP.Net Core的新手。
我有一个ASP.Net核心网站,其中一项任务是将数据从Excel工作表导入用户将上传的数据库。 excel表格可能很大,数据转换任务也很耗时,因此我希望在后台执行它们。即用户将上传工作表,响应将立即发送,后台作业/线程将导入数据。
我正在尝试通过以下方式运行后台作业:
Task.Run(() => ProcessImport(model));
我遇到的问题是Process导入方法调用具有存储库类的服务,这些存储库类通过作为Scoped添加的ASP.Net依赖注入容器访问AppDbContext,并且一旦响应被发回,就会释放上下文。我收到一个运行时异常,你不能在它被处置后使用上下文。
我的问题是,处理这种情况的最佳方法是什么?我应该制作AppDbContext单例吗?我应该在ProcessImport方法中创建一个新的AppDbContext实例,并将其传递给它吗?我读过DbContext不是线程安全的,那么这是一个好方法吗?
答案 0 :(得分:22)
您应该将IServiceScopeFactory
个实例(它的单身人士)传递给您的任务。
在内部任务中,当数据到达时,您应该创建新的CreateScope()
并从该范围请求服务。数据处理完成后 - 处理此范围(但保留对IServiceScopeFactory
的引用以进行下一次运行)。
例如,请参阅this。我用这个库运行小而快的任务。
对于重型/长时间运行的任务,正如格特写的那样,不要相信你的任务总是会完成。准备好重新启动,准备好重新处理相同的数据。
答案 1 :(得分:4)
分类您的问题:
处理这种情况的最佳方法是什么?
API处理长时间运行的任务并不理想。您可以将流程委派给后台应用程序
我应该制作AppDbContext单例吗?
dbContext不应该是Web应用程序场景中的单例,因为它可能会导致管理事务等问题。
处理这种情况的最佳方法是什么?
细分各种服务/流程:
我应该在ProcessImport方法中创建一个新的AppDbContext实例,然后传递它吗?
由于它不是线程安全的,因此在每个线程中创建并使用dbContext类的单独实例。
我看过DbContext不是线程安全的,所以这是一个好方法吗?
有关使用EF dbContext的深入指南,请查看此博客:http://mehdi.me/ambient-dbcontext-in-ef6/