2008-10-16 3 views
2

동일한 MQ 백 엔드와 통신해야하는 여러 스레드 (IIS에서 실행중인 C# 응용 프로그램)가 실행 중입니다. 네트워크 트래픽을 최소화하려면 수행해야 할 작업이있을 때만 백엔드 요청을 보내야합니다. 수행 할 작업이 있는지 모니터링 할 하나의 스레드가 있으며 처리를 시작해야한다는 것을 다른 스레드에 알릴 필요가 있습니다.수행 할 작업이있을 때 스레드 일시 중지 및 알림

CheckIfWorkAvailable() { 
    while(true) { 
    if (queue.Empty != true) { 
     workToBeDone = true; 
    } 
    }//end while loop 
} 

다음 작업자 스레드 :

DoWork() { 
    while(true) { 
    if (workToBeDone == true) { 
     //do work... 
    } 
    else { 
     Thread.Sleep(x seconds) 
    } 
    }//end while loop 
} 

수있는 현재의 솔루션은 모니터 스레드에서, 즉 모니터 스레드 전역 변수를 설정하고 다른 스레드 루프를 갖는 것을 확인을 포함한다 모니터 스레드는 작업자 스레드에게 루프 및 슬립 대신 작업을 알립니다. 작업자 스레드는 작업 중임을 나타내는 카운터를 설정하고 작업이 완료되면 작업 수를 감소시켜 workToBeDone 플래그를 false로 설정할 수 있습니다.

답변

4

WaitHandle과 그 내림차순 클래스를 확인하십시오. EventWaitHandle이 귀하의 필요에 부합 할 수도 있습니다.

+0

나는 똑같은 말을하려고했다. 비슷한 코드에 대해 AutoResetEvent를 사용했습니다. –

1

를 사용할 수 있습니다. 즉, 소비 할 스레드를 설정할 필요가 없으며 완료 할 작업을 기반으로 스레드를 설정할 수 있습니다.

프로젝트에서 CTP를 사용하려는 경우 TPL을 좀 더 고급 동기화 및 작업 기능으로 체크 아웃 할 수 있습니다.

4

켄트가 지적한 WaitHandle 클래스뿐만 아니라 Monitor.Wait과 Monitor도 간단합니다. Pulse/PulseAll이 작업을 쉽게 수행 할 수 있습니다. 그것들은 이벤트 핸들보다 "더 가볍다"(다소 원시적이지만). (당신은 여러 대의 모니터 등을 기다릴 수 없습니다.)

나는 이것을 (생산자 소비자 대기열로) 내 threading article에 예로 들어 있습니다.

0

상태가 충족 될 때 모든 작업자 스레드를 진행하려는 경우 (여기에서 원하는 것처럼 보임) ManualResetEvent를 사용하십시오. 일부 작업을 사용할 수있게 될 때마다 단일 작업자에게 신호를 보내려는 경우에만 AutoResetEvent를 사용하십시오. 특정 수의 스레드가 계속 진행되도록하려면 세마포어를 사용하십시오. 이 유형의 전역 변수는 거의 사용하지 마십시오. 그렇다면 휘발성으로 표시하십시오.

이 상황에서주의하십시오. 하나의 항목이 해제 될 때마다 대기열에 동시에 도착하도록 모든 작업자를 해제하기 때문에 "대기 행렬"을 발생시키지 않으려 고합니다.

관련 문제