如何防止我的线程在工作完成之前退出?
How to prevent my threads from exiting before their work is done?
我有 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,但我不知道如何调试它,在代码中的何处正确释放它?但是,如果不释放它,代码运行良好但线程退出。这可能是道奇先生所说的问题。
根据我对您创建 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 Debugger 简直就是时间领主,可以看到所有平行宇宙。
我有 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,但我不知道如何调试它,在代码中的何处正确释放它?但是,如果不释放它,代码运行良好但线程退出。这可能是道奇先生所说的问题。
根据我对您创建 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 Debugger 简直就是时间领主,可以看到所有平行宇宙。