2012-04-26 3 views
2

메시지를 처리하는 스레드를 기반으로하는 메시지 큐가 있습니다. 스레드의 일부 활동은 VCL 명령 일 수 있으므로 동기화에서 수행됩니다. Synchronize가 호출되면 스레드가 중지됩니다. 샘플 코드 :동기화가 스레드를 멈추는 것처럼 보입니다.

TMessageQ = class (TThread) 
... 
procedure TMessageQ.do_msg; 
begin 
    case CurrentMessage.Command of 
     cQSize: if Assigned (OnSize) then OnSize (CurrentMessage); 
     cQReady: if Assigned (OnReady) then OnReady (CurrentMessage); 
    end; // case 
end; // do_msg/

procedure TMessageQ.doTask (Sender: TObject); 
begin 
    while FQ.Count > 0 do 
    begin 
     FSection.Enter; 
     try 
     CurrentMessage := FQ.Dequeue; 
     finally 
     FSection.Leave; 
     end; // try..finally 
     Synchronize (do_msg); 
    end; // while 
end; // doTask // 

do_msg의 명령문은 처리되지 않습니다. 누군가 내가 뭘 잘못하고 있는지 알아?

+4

주 스레드에서 어떤 현상이 발생합니까? 동기화에는 MessageLoop이 필요합니다. 메인 쓰레드가이 쓰레드를 기다리고 있다면 그것은 알 수 있습니다. –

+4

+1 행크 - 죽은 델파이 애플리케이션에 대한 # 1 이유 파악 - TThread.Synchronize 및 (아마도) TThread.WaitFor(). 행크 (Hank)가 말했듯이, GUI 스레드에서 무엇을 하든지, 그 일을 그만두고 이벤트 핸들러를 종료하고 메시지 처리를 다시 시작합니다. 이 단계에서 문구 'Application.ProcessMessages'가 뇌를 통과 할 경우 - 퍼지하십시오. –

+0

나는 당신이 옳다는 것을 두려워합니다 (아래 comemnt 참조). 그리고 Application.ProcessMessages :-)에 대한 경고에 감사드립니다. 나는 이것을 저녁에 시험 할 것이다. – Arnold

답변

4

TThread.Synchronize() 블록은 주 스레드가 요청을 처리 할 때까지 차단합니다. 주 스레드는 수동으로 Application.ProcessMessages() 또는 CheckSynchronize()을 주기적으로 호출하지 않는 한 요청을 처리하기 위해 활성 메시지 루프가 필요합니다. 스레드의 주 작업이 항상 TThread.Synchronize()에 의해 호출되는 경우 스레드를 전혀 사용하지 않아도됩니다. 대신에 주 스레드에서 타이머 또는 사용자 정의 창 메시지를 사용하고 불필요한 복잡성을 모두 제거 할 수 있습니다.

+0

나는 이것만큼 간단 할까 두려워, 나의 주요 실은 계속된다. 나는 이것을 조사하고 돌아올 것이다. – Arnold

+0

당신 (그리고 헨크와 마틴)이 옳았습니다. 타이머의 종류로 메인 스레드를 사용하여 특정 작업의 지속 시간을 결정했습니다. 두 개의 서로 다른 프로세스가 있기 때문에 여기서 스레드를 사용합니다. 한 프로세스에서는 무언가 발생하고 다른 프로세스에서는 비동기 적으로 결과를 처리합니다. http://stackoverflow.com/questions/9033860/reduce-cpu-time-spent-in-vcl에서 두 개의 스레드를 사용하여 CPU를 많이 사용하는 작업과 그렇지 않은 작업을 구분하는 것이 좋습니다. 이 경우 스레드는 더 복잡하지만 메시지 처리시기를 생각할 필요가 없습니다. 쓰레드는 간결하게 유지하는 한 사물을 간소화합니다. – Arnold

관련 문제