2016-07-23 41 views
-2

我有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

那么,你到底在问什么? – MartynA

+1

当线程代码完成时,线程被销毁。如果你想让你的线程永远活着,你需要在它内部运行一个无限循环。 – Johan

+0

但是线程代码仍然没有完成,线程存在@Johan – Thunderx

回答

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,但由于相同的原因,设计仍然存在缺陷。


现在,当你说你调试它,我猜你的意思是你调试的实际线程代码,但断点在你的代码跃升到另一个地方则达到本月底前?在线程中使用调试器时会出现这种情况。你不能直接进入一个线程,并期望每个顺序断点处于同一线程中 - 我的意思是,如果在不同线程中有多个断点,则调试器很可能从一个跳转到另一个 - 因为再次,它们是多个线程。我建议创建某种工作日志,并且每个线程都会报告其状态和位置。

它字面上就像一个替代宇宙。多个不同的类似线程彼此做的事情略有不同。德尔福调试器就是能够看到所有替代宇宙的时间领主。

+1

我认为变量'lHTTP'最好在线程部分定义。 'TTask.Create(Procedure var lHTTP:TIdHTTP; begin ...',请纠正我,如果我错了 – RepeatUntil

+0

@RepeatUntil感谢您指出,加入我的答案 –

+1

当调试线程时,您可以使用'线程状态“窗口中,选择性地冻结和解冻其他正在运行的线程。通过冻结所有其他线程,可以解决上述问题(断点在线程之间跳转) –

相关问题