TThread の子孫とオブジェクトのリストがあり、それぞれにそのようなスレッドの独自のコピーがあり、CreateEvent() API で作成された Event オブジェクトがあります。
異なるオブジェクトは、イベントの発火によって相互に作用します。つまり、各スレッドは、他のスレッドがそのイベントを発生させるまで待機する必要があります。もちろん、永続的に機能する「マスター」スレッドが 1 つあるため、セルフブロッキングは発生しません。このシステムは、各オブジェクトの Execute メソッドの最後まで問題なく機能します。
アプリを閉じるなどして、すべてのスレッドを中断しようとすると、probkem が表示されます。この場合、各スレッドの Terminate メソッドを呼び出す外部関数が必要です。
for i := 0 to FLayers.Count - 1 do
begin
FLayers.Layer[i].FTerminating := true;
f := true;
while f do
begin
f := FLayers.Layer[i].IsActive;
if f then
begin
Sleep(100);
Application.ProcessMessages;
end;
end;
FLayers.Layer[i].FTerminating := false;
end;
この関数は Form.OnClose() イベントにあります。
問題は、約 2 つのスレッドが正常に終了することですが、他のすべては WaitForSingleObject() 呼び出しで停止します。
procedure TLayerThread.Execute;
begin
FLayer.FIsActive := true;
...............
repeat
//
if Terminated or
FLayer.FTerminating or
(FLayer.FEvent = INVALID_HANDLE_VALUE) then
begin
break;
end;
//
Fres := WaitForSingleObject(FLayer.FEvent, 100); <<<<<<<<<<<<<<<<<<<<<<<<
until Fres <> WAIT_TIMEOUT;
...........
FLayer.FIsActive := false;
end;
すべてのスレッドがその行で停止(ハング) します。タイムアウト値が設定されているにもかかわらず、上記でマークされています。
何か案は?
Delphi 7 と Win XP を使用しています。
前もって感謝します。
ファローアップ -
この問題は、Execute() メソッド内からの Synchronize() 呼び出しでカバーされていることがわかりました。ここで何が悪いのか理解できません。Synchronize() は、ビジュアル コントロールの更新などの通常のことを呼び出しますが、それ以上は何もしません。
デバッガーが示すように、一部のスレッドが WaitForSingleObject() 呼び出しでハングしていますが、これは異なるスレッドを調整するために Execute() メソッドで使用するものではなく、別の呼び出しです。私はそれがここにあると推測できます:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
.................
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);<<<<<<<<<<<<<<<<<<<<<<
finally
EnterCriticalSection(ThreadLock);
end;
..................
私のコードのどこが間違っているのか教えてくれる人はいますか? Execute() メソッド内から Synchronize() を呼び出すことが許可されていないとは聞いたことがありません...