У меня есть потомок TThread и список объектов, каждый из которых имеет свою собственную копию такого потока и все же объект Event, созданный с помощью API CreateEvent ().
Различные объекты взаимодействуют друг с другом, вызывая событие.Т.е. каждый поток должен ждать, пока какой-то другой поток не запустит свое событие.Конечно, есть один «главный» поток, который работает постоянно, поэтому самоблокировка никогда не произойдет.Эта система прекрасно работает до конца метода Execute в каждом объекте.
Проблема возникает, когда я пытаюсь прервать все потоки, например, закрыв приложение.В этом случае мне нужна некоторая внешняя функция, которая вызывает метод 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 ().
Проблема в том, что около двух потоковзавершаются нормально, но другие все останавливаются при вызове 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.
Заранее спасибо.
Продолжение-
Я обнаружил, что проблема заключается в вызове Synchronize () из метода Execute ().Я не могу понять, что здесь не так.Synchronize () вызывает обычные вещи, такие как обновление визуальных элементов управления и ничего более.
Как показывает отладчик, мои потоки зависают при вызове WaitForSingleObject (), но это не то, что я использую в методе Execute ()координировать разные потоки, но какой-то другой вызов.Я могу предположить, что это здесь:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
.................
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);<<<<<<<<<<<<<<<<<<<<<<
finally
EnterCriticalSection(ThreadLock);
end;
..................
Есть ли кто-нибудь там, кто мог бы сказать мне, что не так в моем коде?Я никогда не слышал, что нельзя вызывать Synchronize () из метода Execute () ...