2014-07-10 7 views
-1

콘솔을 볼 때 두 코드 블록이 동일한 효과를 보입니까?
참고 : 현재 저는 여전히 .NET 3.5를 사용 중이며 바인딩되어 있습니다.WaitHandle 기본 동작

첫째 :

for(int i = 0; i<3;i++) 
{ 
    Console.WriteLine(i); 
} 

둘째 :

class Worker 
{ 
    static int i = 0; 
    static ManualResetEvent manualResetEvent = new ManualResetEvent(false);  
    static Object locky = new Object(); 
    static void Work(Object workItem) 
    { 
     WaitHandle[] wait = new [] { manualResetEvent }; 

     while (WaitHandle.WaitAny(wait)) 
     { 
      lock (locky) 
      { 
       Console.WriteLine(i++); 
      } 
     } 
    } 
} 
// main: 

Thread thread = new Thread(Worker.Work); 
thread.Start(); 

for (int i=0;i<3;i++) 
{ 
    Worker.manualResetEvent.Set(); 
} 

는 WaitHandle이 모든 신호와 함께 증가 할 것인가? 모든 신호가 완료 될 때까지 루프가 실행됩니까? 스레드가 이미 작동 중일 때 신호가 무시됩니까?

누군가가이 문제에 불을 붙일 수 있습니까?

+1

두 번째 코드도 컴파일되지 않으므로 동일한 효과가 없습니다. 일단 컴파일 할 코드가 있으면, 직접 해보는 것이 좋습니다. 차이점을 볼 수 있다면 분명히 중요한 차이가 있습니다. 만약 당신이 * 할 수 없다면, 더 합리적인 질문이 될 것입니다. –

+2

'ManualResetEvent'는 이름에서 알 수 있듯이 * 수동 재설정 *을 필요로합니다. 그것은 당신이'Reset' 할 때까지 설정 될 것입니다 - 그래서 당신은 줄거리의 무한 순환을 얻을 것입니다. 또한 값 유형을 잠글 수 없습니다! 어쨌든, 사용 가능한 가장 높은 수준의 추상화를 사용해보십시오. 당신은 멀티 스레딩과 동기화에 대해 알고있는 것보다 너무 낮습니다. 대신에 TPL, DataFlow 및 유사한 친숙한 구조를 살펴보십시오. – Luaan

+0

@ Luaan 내가 누락 된 것을 정확히 고맙다. –

답변

3

ManualResetEvent을 사용 중이므로 일단 이벤트를 알리면 재설정 될 때까지 신호가 계속 전송됩니다. 즉, 한 번 또는 세 번 설정하면 동일한 효과가 나타납니다.

이렇게하면 이벤트가 재설정되지 않기 때문에 작업자가 무한 루프로 들어갈 수 있습니다.

또한 값 유형을 잠글 수 없습니다. 가능하다면, int는 boxed 될 것이고, 여러분이 잠글 때마다 새로운 object을 생성 할 것입니다. 즉, 매번 다른 객체에 잠글 것이고, 잠금을 쓸모 없게 만들 것입니다.

+0

다행히도 최신 C# 컴파일러는 값에 대한 잠금을 명시 적으로 금지합니다 (객체에 직접 박스가없는 경우) - 코드가 컴파일되지 않습니다. – Luaan

+0

@Luaan Cool, 컴파일러가 이것을 시행했는지 확신 할 수 없었습니다. 나는 "당신이 그것을하지 말았어야"대신에 "할 수 없다"라는 상태로 답변을 업데이트했습니다 :) Thanks – dcastro

+0

... Worker.manualResetEvent.Reset()이 호출 될 때까지 끝없이 실행됩니다 ... that 내 누락 된 작품이었습니다. 정확히 알아야 할 것이 었습니다. 감사 –