【发布时间】:2016-07-17 02:59:45
【问题描述】:
我想将 Post 发送到速度较慢的服务器。服务器将在 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)... 这是很自然的,因为我没有检查 Thread.Execute 中的 Terminated。
【问题讨论】:
-
释放线程时,它会等待线程过程返回。它没有。您必须拨打
ProcessMessages的电话。主线程出错,工作线程更出错。你会想退后一步,在其中加入一些设计和抽象。目前,您似乎拥有大量代码,允许任何部分访问任何其他部分。这种方法不会有好处。 -
同意你@DavidHeffernan。但我认为最大的问题是我没有处理 TPostThread.Execute 中的 Terminated 信号。但是当整个 Execute 过程只是一行代码时,我该如何处理呢?
-
您需要能够中止
Post。能做到吗? -
@DavidHeffernan-好问题。我认为我的问题是“二合一”。一次,我的应用程序在关闭时冻结(因为上面的代码)和第二次(如何与 Post 并行运行代码)......好吧,一旦我们解决了第一个问题,它可能会解决。
-
通常,要中止
Post(),您可以使用OnWork...事件在线程的Terminated属性为真时引发异常。但是,这些事件仅在字节实际在任一方向传输时才被调用。如果服务器确实需要 20 多分钟来回复(为什么??),而TIdHTTP只是完全闲置,OnWork...事件将不会被调用。在这种情况下,唯一的选择是Disconnect()来自另一个线程上下文的套接字。即便如此,也不能保证在所有平台上都能正常工作(但在 Windows 上确实如此)。
标签: delphi indy delphi-xe7