ObjectContext 实例已被释放 - 此线程是否安全



我有一个在 Web 应用程序后台运行的System.Threading.Timer集合,该应用程序定期从数据库中检索数据以更新缓存。

有时(不经常(对数据库的调用会失败,并显示错误,例如"ObjectContext 实例已释放,不能再用于需要连接的操作"。

似乎它有时会被另一个线程处理,但是当每个计时器运行时,它会创建一个全新的 DbContext,所以我不确定这是怎么回事。

我正在使用 StructureMap 创建一个嵌套容器,以便它独立运行,并且我已经验证了它确实为每个计时器创建了一个新的 DbContext。

var a = new A();
var b = new B();
var timer1 = new Timer(x => a.Update(container), null, TimeSpan.Zero, TimeSpan.FromMinutes(60));
var timer2 = new Timer(x => b.Update(container), null, TimeSpan.Zero, TimeSpan.FromMinutes(60));
public class A 
{
    public void Update(IContainer container)
    { 
        using (var nestedContainer = container.GetNestedContainer()) {
            // This will create a new DbContext and will be disposed 
            // when the nested container is disposed
            var repository = nestedContainer.GetInstance<IRepositoryA>();
            // Sometimes fails here when it's accessing the DbContext
            repository.GetStuff();
        }
    }
}
public class B
{
    public void Update(IContainer container)
    { 
        using (var nestedContainer = container.GetNestedContainer()) {
            var repository = nestedContainer.GetInstance<IRepositoryB>();
            repository.GetStuff();
        }
    }
}

这是结构图配置。因此,每当创建存储库时,它都会创建一个新工厂,进而创建一个新的MyDbContext。

For<IDbContextFactory<MyDbContext>>().HybridHttpOrThreadLocalScoped()
    .Use(() => new DbContextFactory());

事实证明,这是由HybridHttpOrThreadLocalScoped StructureMap插件引起的,当本地线程处理嵌套容器时,该插件会处理DbContext,因此其他线程无法再使用它。删除它并将我的 StructureMap 配置更改为在 HTTP 请求的生命周期中使用嵌套容器解决了这个问题。

最新更新