如何与Indy.Post并行执行代码

时间:2016-03-29 13:48:06

标签: delphi indy delphi-xe7

我想将帖子发送到速度慢的服务器。服务器在20分钟(或更长时间)内不会回答,整个应用程序冻结。

我想解冻GUI,同时等待Post响应处理以前Post命令中的数据。

以下是我发送Post命令的方法:

  { POST }
  procedure TJob.SendToServer; 
  begin
  ...  
  lHTTP := TIdHTTP.Create(NIL);
  TRY
    TRY
     Server.Rspns:= lHTTP.Post(ApiServer, MegaSeqFileName);        { This won't freeze the GUI anymore because now TJob.SendToServer function is called in a TPostThread thread }                                      
    EXCEPT
     on E: Exception DO                                                                                  { Catch Internet connection problems }
      begin
       Application.ProcessMessages;
       Status:= jsNotSubmited;
       ParentTask.Log.AddError(E.Message);  
       EXIT;                                                                                          
      end;
    END;
  FINALLY
    FreeAndNil(lHTTP);
  END;

这是线程代码:

TYPE
  TPostThread= class(TThread)
  public
    Job: TJob;
    procedure Execute; override;
    procedure Done;
  end;

procedure TPostThread.Done;
begin
 Job.ThreadDone:= TRUE;
end;

procedure TPostThread.Execute;
begin
 Job.SendToServer;                                           { Send job and collect results }
 Synchronize(Done);
end;

这就是我启动线程的方式

   Job.ThreadDone:= FALSE;
   Thread:= TPostThread.Create(TRUE);
   Thread.Job:= Job;                             
   Thread.FreeOnTerminate:= FALSE;              
   Thread.Start;                                 {This calls: Job.SendToServer }

   REPEAT
     DelayEx(2000);
     if Aborted then
      begin
       MesajInfo('Task aborted.');
       Thread.Terminate;
       FreeAndNil(Thread); <----freezes here!
       EXIT(FALSE);
      end;
     //todo: run other tasks here (more exactly get results from previous Posts and send them to a different web server)
   UNTIL Job.ThreadDone;
   FreeAndNil(Thread);

问题是,当我设置Aborted = True时,线程不会退出。它冻结在FreeAndNil(Thread)上......这很自然,因为我没有检查Threadated.Execute中的Terminated。

1 个答案:

答案 0 :(得分:1)

我有这个临时解决方案,没有线程,基于@RemyLebeau的想法:

procedure TJob.OnHTTPProgress(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
 if UserAborted=true then TIdHTTP(ASender).Disconnect;
 Application.ProcessMessages;
end;

我知道这不是好的答案,只是一个肮脏的黑客(这就是为什么我永远不会将这个答案标记为已被接受),但它使我的程序工作,我非常需要制作它会在接下来的1-2周内发挥作用。它允许我做两件事:停止程序(在上传期间)并防止GUI冻结。

我可以稍后再回来解决这个问题。