我写了一个.NET + EF应用程序。一切工作正常,在一个单一的线程。多线程 - 这是另一回事。实体框架并发刷新和更新
在我的EF对象中,我有一个整数计数器。此属性被标记为“并发模式=固定”。基本上,我想要做的是更新这个计数器的几个线程。 像这样操作:
this.MyCounter -= 1;
因为它的并发模式已更改为“固定”,当我特林更新这已经更改属性 - 一个OptimisticConcurrencyException
被抛出。
为了解决这个并发问题,我使用这个代码:
while (true)
{
try
{
this.UsageAmount -= 1; // Change the local EF object value and call SaveChanges().
break;
}
catch (OptimisticConcurrencyException)
{
Logger.Output(LoggerLevel.Trace, this, "concurrency conflict detected.");
EntityContainer.Instance.Entities.Refresh(RefreshMode.StoreWins, this.InnerObject);
}
}
这段代码的结果是一个无限(或也许它只是看起来像)循环。每调用一次this.UsageAmount -= 1
就会抛出一个OptimisticConcurrencyException
,这会导致循环再次运行。
我的EntityContainer.Instance.Entities
是提供EF上下文PER THREAD的单例类。这意味着每个线程都有独特的上下文。代码:
public sealed class EntityContainer
{
#region Singlethon Implemantation
private static Dictionary<Thread, EntityContainer> _instance = new Dictionary<Thread,EntityContainer>();
private static object syncRoot = new Object();
public static EntityContainer Instance
{
get
{
if (!_instance.ContainsKey(Thread.CurrentThread))
{
lock (syncRoot)
{
if (!_instance.ContainsKey(Thread.CurrentThread))
_instance.Add(Thread.CurrentThread, new EntityContainer());
}
}
return _instance[Thread.CurrentThread];
}
}
private EntityContainer()
{
Entities = new anticopyEntities2();
}
#endregion
anticopyEntities2 _entities;
public anticopyEntities2 Entities
{
get
{
//return new anticopyEntities2();
return _entities;
}
private set
{
_entities = value;
}
}
}
BTW,调用Entities.Refresh
方法之后 - 它看起来像它的工作(对象状态是不变,属性格式值是在数据库中究竟存在)。
我该如何解决这个并发问题?
你能张贴代码你提到'EntityContainer.Instance.Entities'的单身类? - 只是你提供的部分“每个线程的EF上下文”。 – lukiffer
EntityContainer.Instance.Entities代码被插入到帖子中。 – No1Lives4Ever
当你说*每个*调用抛出时,这是否可以归结为某些线程被阻止进行更新,因为它们每次都被打到数据库?数据库中的值是否真的在变化? – shambulator