2012-01-14 2 views
1

WCF 서비스와 레코드를 가진 리소스 (식별 할 수있는 ID가 있음)가 있습니다. 내가동시성 - 한 번에 하나의 리소스 편집

public void UpdateMySpecialEntity(Entity foo) 
{ 
    ConcurrencyIdManager.Instance.RequestAndWaitForIdGrant(foo.Id); 
    try { 
     // do something with the entity foo 
    } 
    finally { ConcurrencyIdManager.Instance.ReleaseGrantForId(foo.Id); } 
} 

지금까지 구현 정확이 내 WCF 서비스에 따라서

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); 
     } 
    } 

: 그래서 내가 조금 자원 도우미를 작성했습니다 - 나는 단지 한 ID가 동시에 액세스 할 수 있는지 싶어? :-)

+0

코드를 올바르게 읽으면 한 번에 하나의 리소스로 작업하지 않으므로 주어진 시간에 최대 한 개의 스레드 만 리소스에서 작업 할 수 있습니다. 리소스 당 잠글 수있는 객체를 갖는 것이 더 쉬울까요? –

+0

내가 얻으려고하는 것은 : * 다중 스레드에 의해 다른 ID로 여러 엔티티를 업데이트 할 수 있어야합니다. * 동시에 ID X로 엔티티를 업데이트 할 수 없어야합니다. "리소스 당 잠글 수있는 객체"가 무슨 뜻인지 잘 모르겠습니다. 항목을 다시 소환하는 것을 의미하는 경우 - 금액이 무한하기 때문에 불가능합니다 (이 경우 데이터베이스를 ressource로 가정) – damike

+0

사용중인 .NET 버전은 무엇입니까? ConcurrentBag 에 액세스 할 수 있습니까? 또한이 코드는 특정 ID뿐만 아니라 목록 에 대한 전체 액세스를 차단하므로 대기 및 펄스로 추가 차단을 수행 할 필요가 없습니다. – oleksii

답변

0

메모를 올바르게 읽는 경우 ID 3,4,5가 동시에 편집하려면 id 5 인 두 개의 스레드를 차단하고 서로 기다려야합니다.

그런 경우 잠금 객체의 동시 수집을 사용하고 해당 ID에 대해 객체에 대한 간단한 잠금을 사용하십시오.

in pseudo C#

+1

Thx 많이 !! 안전하게 lockObjects에서 콘텐츠를 안전하게 제거하려면 어떻게해야합니까? – damike

+0

lockObject.TryRemove (foo.id) –

관련 문제