我想将帖子发送到速度慢的服务器。服务器在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。
答案 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冻结。
我可以稍后再回来解决这个问题。