Reputation: 40012
I have the property State
which, when set, updates an entity in the database.
The problem is that this property is being set across multiple threads and sometimes the job field is attached to two contexts at the same time, resulting in the following exception:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I have tried to use a lock around the using
statement, but this doesn't work:
private Job job;
public string State
{
get
{
return job.State;
}
set
{
lock (job)
{
using (MyEntities context = new MyEntities())
{
context.Jobs.Attach(job);
job.State = value;
context.SaveChanges();
}
}
}
}
What is the best way to go about this?
Upvotes: 4
Views: 1414
Reputation: 40012
The problem was that locking on job
wasn't working. I am not sure why.
Implementing a dedicated lock object
works perfectly:
private Job job;
private static object jobInstanceLock;
public string State
{
get
{
return job.State;
}
set
{
lock (jobInstanceLock)
{
using (MyEntities context = new MyEntities())
{
context.Jobs.Attach(job);
job.State = value;
context.SaveChanges();
}
}
}
}
Upvotes: 0
Reputation: 10476
If you are OK with detaching the object and you loose nothing after, you can simply detach it from context after saving:
lock (job)
{
using (MyEntities context = new MyEntities())
{
context.Jobs.Attach(job);
job.State = value;
context.SaveChanges();
context.Detach(job); // Detach the object
}
}
UPDATE:
I already tested a similar scenario and I found no problem. I suspect that the entity job
was attached to some context before it enters the critical section. If job
has some relations you can check whether an entity is attached to some context or not via the proposed way in http://blogs.msdn.com/b/alexj/archive/2009/06/08/tip-24-how-to-get-the-objectcontext-from-an-entity.aspx
Upvotes: 1