C# 实体框架:如何跨多个线程处理DbContext的多个实例

C# 实体框架:如何跨多个线程处理DbContext的多个实例,c#,asp.net-mvc,multithreading,entity-framework,autofac,C#,Asp.net Mvc,Multithreading,Entity Framework,Autofac,我使用Autofac注入依赖项,我的应用程序需要在后端工作,我使用Quartz触发后台工作人员 我使用以下代码: builder.RegisterType<AppContext>() .AsSelf().InstancePerDependency() builder.RegisterType() .AsSelf().InstancePerDependency() 允许每个工作进程(线程)拥有DbContext类的新实例,我这样做是因为DbContex

我使用Autofac注入依赖项,我的应用程序需要在后端工作,我使用Quartz触发后台工作人员

我使用以下代码:

builder.RegisterType<AppContext>()
               .AsSelf().InstancePerDependency()
builder.RegisterType()
.AsSelf().InstancePerDependency()
允许每个工作进程(线程)拥有
DbContext
类的新实例,我这样做是因为
DbContext
类不是线程安全的

当我去更新或创建它所说的东西时,真正的问题就开始了

在ObjectStateManager中找不到对象

我已经看到了一些解决方案,比如分离和连接实体。但是在我的例子中,我的存储库方法正在被前端(Asp.NETMVC)使用。我不想复制这些方法,一个是来自web应用程序的特定DB调用,另一个是来自后台工作者的


有解决办法吗

使用
InstancePerDependency()
,Autofac将不仅为每个辅助对象创建一个DbContext,而且每次创建的对象需要一个DbContext时都会创建一个DbContext。假设您使用3个存储库,每个存储库都有一个上下文构造函数参数,这意味着三个不同的上下文(更不用说您必须自己管理处置,并且您可能还希望为每个web请求创建一个上下文,这不允许您这样做)

您需要的是这个Autofac Quartz集成包:


根据文档,这为每个作业创建了一个生命周期范围。因此,如果将上下文注册为
InstancePerLifetimeScope()
,则一个作业(具有自己的生存期范围)内的所有内容都将获得相同的上下文对象。这可能会解决您的问题。

使用
InstancePerDependency()
,Autofac将不仅为每个辅助对象创建一个DbContext,而且每次创建的对象需要一个DbContext时都会创建一个DbContext。假设您使用3个存储库,每个存储库都有一个上下文构造函数参数,这意味着三个不同的上下文(更不用说您必须自己管理处置,并且您可能还希望为每个web请求创建一个上下文,这不允许您这样做)

您需要的是这个Autofac Quartz集成包:


根据文档,这为每个作业创建了一个生命周期范围。因此,如果将上下文注册为
InstancePerLifetimeScope()
,则一个作业(具有自己的生存期范围)内的所有内容都将获得相同的上下文对象。这可能会解决您的问题。

我确实在一个示例控制台应用程序中集成了topshelf的Api,它工作得很好,但当我在实际的Asp.NET MVC应用程序中实现时,作业没有运行,在输出窗口中,我看到一些异常,表明服务配置正确,它告诉我位于.vs目录下的主web项目中的applicationhost文件有问题。任何解决方案?我可以通过注册模块
builder.RegisterModule(新的QuartZautofactoryModule())使其正常工作;我确实在一个示例控制台应用程序中集成了topshelf的Api,它运行得很好,但当我在实际的Asp.NET MVC应用程序中实现时,作业没有运行,在输出窗口中,我看到一些异常,表明服务配置正确,它告诉我位于.vs目录下的主web项目中的applicationhost文件有问题。任何解决方案?我可以通过注册模块
builder.RegisterModule(新的QuartZautofactoryModule())使其正常工作;这里是一个与Autofac和Quartz集成的通用示例项目这里是一个与Autofac和Quartz集成的通用示例项目