我已经编写了一个.NET + EF应用程序。在单个线程上一切正常。但在多个线程上就不同了。
在我的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
方法之后——看起来它正在工作(对象状态为“Unchanged”,属性值正好与数据库中存在的相同)。
我该如何解决这个并发问题?
EntityContainer.Instance.Entities
的代码?- 只需要提供“每个线程一个EF上下文”的部分。 - lukiffer