我有一个TThread的后代和一个对象列表,每个对象都有自己的此类线程副本,但还有使用CreateEvent()API创建的Event对象。多线程的Delphi 7应用程序 - 应用程序终止的问题
不同的对象通过事件触发相互作用。即每个线程必须等待,直到其他线程将触发其事件。当然,有一个“主”线程永久工作,所以自我阻止永远不会发生。这个系统工作得很好,直到每个对象的Execute方法结束。
当我试图中断所有线程时,出现probkem,例如通过应用关闭。在这种情况下,我需要它调用终止每个线程的方法,一些外部函数:
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。
在此先感谢。
Followup--
我发现这个问题是在Synchronize()调用覆盖从execute()方法中。我无法理解这里出了什么问题。 Synchronize()调用通常的东西,比如视觉控件更新等等。
正如调试器显示的那样,我的线程中有很多挂在WaitForSingleObject()调用上,但这不是我在Execute()方法中用于协调不同线程,而是另一个调用。我可以假设它是在这里:
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
.................
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);<<<<<<<<<<<<<<<<<<<<<<
finally
EnterCriticalSection(ThreadLock);
end;
..................
有没有人在那里,谁可以告诉我什么是我的代码错了?我从来没有听说过,这是不允许从内部调用同步()execute()方法...
对不起,但是你有关过程终止事件吗?请注意,我不是关于进程终止。让我们把它看作是一个过程,中断所有的线程。例如。我有“停止处理”菜单项,它不关闭应用程序,但只是中断所有线程,就像上面显示的那样。而且我无法等待事件的发生,因为一般来说,每个线程都必须单独中断。简而言之,我的问题是“为什么一个线程终止会导致另一个线程挂起?”谢谢。 – Alex 2010-12-18 15:50:27
如果你在OnClose()或其他方法中调用它,这无关紧要。通过为每个线程使用一个关闭事件,您还可以单独结束每个线程。 – Robert 2010-12-24 22:05:04