I have a collection of System.Threading.Timer
that run in the background of a webapp that periodically retrieve data from a DB to update the cache.
Occasionally (not often), calls to the DB will fail with an error such as "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection".
It seems like it's sometimes being disposed by another thread, but when each timer runs, it'll create a brand new DbContext, so I'm not sure how that can be the case.
I'm using StructureMap to create a nested container, so that it runs in isolation, and I've verified that it does indeed create a new DbContext for each timer.
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();
}
}
}
Here's the StructureMap config. So whenever a repository is created it will create a new factory which in turn creates a new MyDbContext.
For<IDbContextFactory<MyDbContext>>().HybridHttpOrThreadLocalScoped()
.Use(() => new DbContextFactory());