我有一个WCF服务和一个包含记录的资源(具有识别它们的ID)。我想只能同时访问1个ID - 所以我写了一个小资源帮助器:
public sealed class ConcurrencyIdManager
{
private static object _syncRootGrant = new object();
private static List<int> _IdsInUse = new List<int>();
... // singleton
public void RequestAndWaitForIdGrant(int id)
{
lock (_syncRootGrant)
{
while (_IdsInUse.Where(i => i == id).Count() != 0)
{
Monitor.Wait(_syncRootGrant);
}
_IdsInUse.Add(id);
}
}
public void ReleaseGrantForId(int id)
{
lock (_syncRootGrant)
{
_IdsInUse.Remove(id);
Monitor.PulseAll(_syncRootGrant);
}
}
所以在我的WCF服务中我有
public void UpdateMySpecialEntity(Entity foo)
{
ConcurrencyIdManager.Instance.RequestAndWaitForIdGrant(foo.Id);
try {
// do something with the entity foo
}
finally { ConcurrencyIdManager.Instance.ReleaseGrantForId(foo.Id); }
}
到目前为止,实施是否正确? : - )
答案 0 :(得分:0)
如果你正在读你的笔记,你想要同时编辑id 3 4和5,但是两个ID为5的线程要阻塞并等待彼此。
在这种情况下,使用锁定对象的并发集合,并对该Id使用对象的简单锁定。
e.g。在伪c#
中ConcurrentDictionary<int,object> lockObjects = new ConcurrentDictionary<int,object)
public void UpdateMySpecialEntity(Entity foo)
{
object idLock = lockObject.GetOrAdd(foo.id,new object());
lock (idLock)
{
// do lock sensitive stuff in here.
}
}