2013-06-25 4 views
0

다른 스레드에서 액세스 할 수있는 정적 대기열이 있습니다.큐를 열거/열거합니까?

대기열에는 add/remove/set에서 제대로 잠그는 래퍼가 구현되어 있습니다. 또한 큐의 복사본을 잠그고 반환하는 메서드가 있지만 이것은 새로운 열거 형을 만듭니다. 이는 낭비이기 때문에 필요한 경우에만 호출하고 싶습니다.

내가 불필요하게 큐를 복사하고 싶지 않아요,하지만 난에에 열거하고있어 동안에 열거하는 큐가 변경되는 경우 예외를 throw 할 수 있습니다.

을 열거하면서 이러한 예외를 throw하는 기회가 (때문에 위의 과정의 이유) :

  • QueueWrapper.InnerQueue.Any()
  • QueueWrapper.InnerQueue.FirstOrDefault(o => o.Something)
  • QueueWrapper.InnerQueue.Except(element)
  • (모든 빈)

여기서 QueueWrapper.InnerQueueQueueWrapper.GetQueueCopy()으로 대체해야합니까?

+1

질문에 대답하는 방법이 확실하지 않지만 참고로 .NET에서 사용할 수있는 동시 대기열이 있습니다. http://msdn.microsoft.com/fr-fr/library/vstudio/dd267265.aspx – C4stor

+0

* C4stor *이 맞습니다. ** 내장 된 구현을 사용할 수 있다면 ** 크게 단순화 할 수 있습니다. – Pragmateek

답변

0

열거 형은 기본 컬렉션을 변경할 때만 throw됩니다. LINQ 연산자 (Any, FirstOrDefaultExcept)는 컬렉션을 변경하지 않으므로 throw하지 않습니다.

+0

아니요 :). 그러나'Any','First' 또는'Except'를 호출하는 스레드 중 하나가 다른 스레드가 위 메서드를 실행하는 동안 컬렉션을 수정하면 예외를 throw 할 수 있습니까? – SoonDead

+0

네,하지만 그건 당신이 준비 할 수있는 것이 아닙니다. 이 코드를 동기화 ('잠금')하지 않고 스레드 안전성이 필요하면 예, 불변의 콜렉션이 필요합니다. 그러나 코드를 동기화하면 옵션 인 경우 시작해야합니다. 이 경우, 위의 설명은 여전히 ​​유효합니다. –

0

표시되는 모든 작업은 실제로 대기열을 열거하므로이 기간 동안 변경할 수 없으므로 대기열의 업데이트 작업을 잠그는 방식에 따라 스레드 안전성이 보장됩니다.

열거 형을 보호해야하는 경우 더 높은 수준의 잠금이 필요합니다.

당신이 ReaderWriterLockSlim ( http://msdn.microsoft.com/library/system.threading.readerwriterlockslim.aspx)를 사용할 수 있습니다 독자가 이미있을 때 새로운 독자를 잠금 방지하기 위해, 최적합니다.

당신은 것 같은 코드 :

ReaderWriterLockSlim rwls = new ReaderWriterLockSlim(); 
... 
rwls.EnterReadLock(); 
try 
{ 
    // some enumeration 
} 
finally 
{ 
    rwls.ExitReadLock(); 
} 
... 
rwls.EnterWriteLock(); 
try 
{ 
    // some bulk update 
} 
finally 
{ 
    rwls.ExitWriteLock(); 
} 

당신이 어떤 주어진 시간에 실행 N 개의 병렬 열거하지만 단 하나의 업데이트을 가질 수 이쪽으로.

관련 문제