2011-08-11 3 views
4

別のスレッドで関数を実行し、スレッドが終了するまで待つ必要があります。同期を使用している問題

例えば、ここで本来の機能があります:上記のスレッドのコードが動作しない理由を

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実行されないされない:

Procedure Search; 
begin 
    CallA; 
    CallB; 
end; 

これは修正機能です私がSynchronizeTMyThread.Executeの中に使うと?

答えて

5

Synchronizeはアプリケーションのメッセージループ内でメソッドを呼び出します。 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が更新されます。 1つの検索手順にすべて含まれるべきではありません。 – mj2008

1

Delphiのtthreadクラスには、onThreadTerminateというイベントがあります。 これは、スレッドがexecuteメソッドを終了するときに、アプリケーションスレッドのコンテキストで呼び出されます。

このイベントは、アプリケーションで使用できます。