我有10个线程一起工作。启动线程后,15秒后所有线程在完成任务之前退出,并且只剩下一个线程。
我的代码:
procedure TForm1.Button2Click(Sender: TObject);
begin
AA;
BB;
CC;
DD;
EE;
FF;
GG;
HH;
II;
JJ;
end;
procedure TForm1.AA; //same procedure for BB,CC,DD,EE.FF,JJ,HH,II,JJ
begin
lHTTP := TIdHTTP.Create(nil);
TTask.Create(Procedure
try
//HTTP Opertations
finally
end;
end).Start;
end;
注意,我不能Free
HTTP组件,因为如果我得到一个AV,我不知道如何调试它,在代码中正确释放它的位置?但是,如果没有释放它,代码运行良好但线程退出。这可能是道奇先生所说的问题。
答案 0 :(得分:3)
根据我看到你创建TIdHTTP
组件的方式,这是完全错误的。您不应该在线程外部创建对象,然后在线程内部使用它。这不是线程安全的。您应该在与其使用位置相同的线程中创建它。这就是为什么你也无法释放它,所以你实际上有两个问题需要同时解决。
我也意识到你的lHTTP
变量不在你的代码范围内,所以我假设你在一些全局(或其他共享)位置声明了它。每个线程都需要自己的变量用于自己的实例。
所以你的代码应该看起来更像这样:
procedure TForm1.AA; //same procedure for BB,CC,DD,EE.FF,JJ,HH,II,JJ
begin
TTask.Create(Procedure
var
lHTTP: TIdHTTP;
begin
lHTTP := TIdHTTP.Create(nil);
try
//HTTP Opertations
finally
lHTTP.Free;
end;
end).Start;
end;
其他组件(例如TADOConnection
)甚至会因为尝试这样的事情而完全失败并崩溃(因为这些组件使用COM)。幸运的是,TIdHTTP
不使用COM,但出于同样的原因,设计仍然存在缺陷。
现在,当你说你调试它时,我猜你的意思是你调试了实际线程中的代码,但断点在它到达此结束之前跳转到代码中的另一个地方?在线程中使用调试器时可以预料到这一点。你不能只是进入一个线程并期望每个顺序断点都在同一个线程中 - 我的意思是,如果你在不同的线程中有多个断点,你的调试器很可能会从一个跳转到另一个 - 因为, ,他们是多线程。我建议创建某种工作日志,每个线程报告其状态和位置。
它实际上就像一个替代宇宙。多个不同的类似线程做的事情略有不同。 Delphi调试器只是时间领主,可以看到所有备用宇宙。