并发 - 一次编辑1个资源

时间:2012-01-14 11:40:54

标签: c# concurrency

我有一个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); }
}

到目前为止,实施是否正确? : - )

1 个答案:

答案 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.
    }
}