2011-12-27 2 views
3

저는 .NET/Threads에 익숙하며 누구든지이 연습에서 저를 도울 수 있는지 알고 싶습니다. 나는 스레드 잠금없이 작동하도록하기 위해 주석을 대체해야합니다.NET 소비자/생산자 (대기열)

private Queue<int> queue; 

public void ConsumeFunc(){ 
    while (true){ 
     // 1 
     while (/* 2 */){ 
     // 3 
     } 
     int element = queue.Dequeue(); 
     // 4 
     Console.WriteLine("Consume element: " + element); 
     Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(0, 2) * 1000); 
    } 
} 

private void ProduceFunc(){ 
    while (true) { 
     // 1 
     queue.Enqueue(DateTime.Now.Millisecond); 
     // 2 
     // 3 
     Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(0, 2) * 1000); 
    } 
} 

나는이 관리를하지만

public void ConsumerFunc(){ 
    while (true){ 
     Monitor.PulseAll(queue); // 1 
     while (queue.Count == 0){ /* 2 */ 
      Monitor.Wait(queue); // 3 
     } 
     int element = queue.Dequeue(); 
     lock (queue) // 4 
     Console.WriteLine("Consume element: " + element); 
     Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(0, 2) * 1000); 
    } 
} 


public void ProducerFunc(){ 
    while (true) { 
     lock (queue) // 1 
     queue.Enqueue(DateTime.Now.Millisecond); 
     Monitor.PulseAll(queue); // 2 
     // 3 ??? 
     Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(0, 3) * 1000); 
    } 
} 

을 완료하고 다음과 같은 오류 제공 아니에요 : 개체 동기화 방법을 동기화되지 않은 코드 블록에서 호출되었습니다., , Monitor.PulseAll(queue);

+0

+1. 정말로 깔끔하게 묻는 질문! –

답변

1

그 대신 tha 동기화를 직접 구현하기 위해 싸우는 중, BlockingCollection을 살펴보십시오. 모든 동기화를 처리하며 Queue 클래스와 Monitor 클래스를 사용하여 만들 수있는 것보다 더 우수한 실적을 보입니다.

.NET 설명서에는 스택 오버플로 및 그 밖의 다른 예제가 많이 있습니다. 내 기사가 유용 할 수 있습니다. 도움을 요청하기 전에 문제를 해결하기위한 시도를 보여주기 위해 http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=821

+0

목표가 대기열을 작성하는 것이라면 ConcurrentQueue를 사용할 수도 있습니다. http://msdn.microsoft.com/en-us/library/dd267265.aspx – Mathias

+0

@Mathias : 'BlockingCollection'은 는 기본적으로'ConcurrentQueue'를 지원 저장소로 사용합니다. 나는 아직 자체적으로'ConcurrentQueue'를 사용하는 것이 더 나은 경우를 가로 질러 실행하지 못했습니다. –