如何在工作完成之前阻止我的线程退出?

时间:2016-07-23 21:30:33

标签: multithreading delphi delphi-10-seattle

我有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,我不知道如何调试它,在代码中正确释放它的位置?但是,如果没有释放它,代码运行良好但线程退出。这可能是道奇先生所说的问题。

1 个答案:

答案 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调试器只是时间领主,可以看到所有备用宇宙。