【发布时间】:2012-11-11 13:19:25
【问题描述】:
我编写了一个 .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 上下文。这意味着每个线程都有一个唯一的上下文。代码:
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;
}
}
}
顺便说一句,在调用 Entities.Refresh 方法之后 - 看起来它正在工作(对象状态未更改,属性值正是数据库中存在的值)。
如何解决这个并发问题?
【问题讨论】:
-
你能贴出你提到的单例类的代码
EntityContainer.Instance.Entities吗? - 只是您提供“每个线程的 EF 上下文”的部分。 -
EntityContainer.Instance.Entities 代码被插入到帖子中。
-
当你说 every 调用抛出时,这可能是因为某些线程被阻止进行更新,因为它们每次都被击败到数据库?数据库中的值是否真的在变化?
-
这段代码可以正常工作一段时间......但是,有时它会进入“问题模式”,这会为每个字符串抛出 OptimisticConcurrencyException 以更改值。我不知道它为什么或何时进入此模式。看起来很随意。当我检查是否有另一个线程正在尝试执行相同的操作时 - 在我看来,当前没有另一个线程正在运行(但不能保证这一点)。
-
所以当它遇到“问题模式”时,DB 值根本不会发生变化,看起来每个线程都在抛出每次?为了清楚起见,如果 DB 值仍在变化,那么在某个地方,不知何故,有一个线程仍在成功进行更新?
标签: c# entity-framework concurrency refresh updates