2011-08-11 5 views
4

분리 된 스레드에서 함수를 실행하고 스레드가 완료 될 때까지 기다려야합니다.동기화 사용 중 문제

Procedure Search; 
begin 
    CallA; 
    CallB; 
end; 

이 수정 된 기능입니다 : : 스레드 위의 코드는 작동하지 않는 이유

Procedure Search; 
var 
    testMyThread: TMyThread; 
    Done: Boolean; 
begin 
    // create a new thread to execute CallA 
    testMyThread:=TMyThread.Create(False,Done); 
    WaitForSingleObject(testMyThread.Handle, INFINITE); 
    if not Done then 
    begin 
    TerminateThread(testMyThread.Handle, 0); 
    end 
    else; 
    CallB; 
end 

unit uMyThread; 

interface 

uses classes; 

type 
    TMyThread = class(TThread) 
    private 
    { Private declarations } 
    FDone: ^boolean; 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(const aSuspended: boolean; var Done: boolean); 
    procedure CallA; 
    end; 

implementation 

uses uMain; 

constructor TMyThread.Create(const aSuspended: boolean; 
    var Done: boolean); 
begin 
    inherited Create(aSuspended); 
    FDone := @Done; 
end; 

procedure TMyThread.CallA; 
begin 
    // enumurating several things + updating the GUI 
end; 

procedure TMyThread.Execute; 
begin 
    inherited; 
    Synchronize(CallA); // << the problem 
    FDone^ := true; 
end; 
end. 

당신이 말해 줄 수는 (CallA가 실행되고 있지 않습니다 예를 들어

, 여기에 원래의 기능입니다) SynchronizeTMyThread.Execute 안에 넣으면?

답변

5

동기화는 응용 프로그램의 메시지 루프 내에서 메서드를 호출하기 때문에. WaitForSingleObject를 사용하면 모든 응용 프로그램을 보류 상태로 둘 수 있습니다. 이것을 시도하십시오 :

Procedure Search; 
    var 
    testMyThread: TMyThread; 
    Done: Boolean; 
    begin 
    // create a new thread to execute CallA 
    testMyThread:=TMyThread.Create(False,Done); 

    while (not Done) and (not Application.Terminated) do 
     Application.ProcessMessages; 

    if not Application.Terminated then 
     CallB; 
    end 
+2

이것은 실제로 해결책이지만 폼을 스레드 대기를 차단하지 않도록 조정해야합니다. 결국, 현재 최종 효과는 변경된 것이 없으며 단지 합병증 만 추가되었습니다. 스레드가 시작되어야하고 IT가 작업을 수행해야하며 결국 UI가 업데이트됩니다. 모든 검색 절차에 포함되어서는 안됩니다. – mj2008

1

델파이 tthread 클래스에는 onThreadTerminate라는 이벤트가 있습니다. 스레드가 execute 메서드를 벗어날 때 응용 프로그램 스레드의 컨텍스트에서 호출됩니다.

응용 프로그램에서이 이벤트를 사용할 수 있습니다.