并发-每次编辑1个资源

本文关键字:1个 资源 编辑 并发 | 更新日期: 2023-09-27 18:20:28

我有一个WCF服务和一个带有记录的资源(具有标识它们的ID)。我希望只有一个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个资源

如果我读对了你的笔记,你希望id的3、4和5同时编辑,但id为5的两个线程要阻塞并等待对方。

在这种情况下,使用锁对象的并发集合,并对该Id的对象使用简单的锁。

例如在伪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.
    }
}