这段代码似乎不是获取线程结果的正确方法,即使表单没有冻结,我可以执行不同的其他任务,也许是另一个请求,因此线程数不会等于一个时间,可能同时最多5个请求,但不依赖于彼此。
如何以“好”的方式做到这一点?
function TEApi.FApiRequest(Request: string) : string;
var
RequestThread : TApiSecureRequest; {TThread}
begin
RequestThread := TApiSecureRequest.Create(Self, Request);
while(NOT RequestThread.Terminated) do
Application.ProcessMessages;
Result := RequestThread.FResponse;
RequestThread.Free;
end;
procedure TApiSecureRequest.Execute;
begin
{do some HTTP requests, which is freezing the Mainform without threading}
FResponse = Result_of_execution;
Terminate;
end;
答案 0 :(得分:4)
请勿使用Application.ProcessMessages
。这是糟糕的代码设计的例子,你应该避免使用它。
相反,使用线程回调或消息。例如:
<强> uAPISecureRequestThread.pas 强>
unit uAPISecureRequestThread;
interface
uses
System.Classes;
type
TApiSecureRequestThread = class(TThread)
private
FResponse: String;
protected
procedure Execute; override;
public
constructor Create;
property Response: String read FResponse;
end;
implementation
constructor TApiSecureRequestThread.Create;
begin
inherited Create(TRUE);
FreeOnTerminate := TRUE; // automatically free thread on terminate
end;
procedure TApiSecureRequestThread.Execute;
begin
// do the work here and assign result to FResponse
end;
end.
<强> uMainForm.pas 强>
unit uMainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TfrmMain = class(TForm)
btCreateThread: TButton;
procedure btCreateThreadClick(Sender: TObject);
private
procedure ASRThreadTerminate(Sender: TObject);
public
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
uses
uApiSecureRequestThread;
procedure TfrmMain.btCreateThreadClick(Sender: TObject);
var
asr_thread: TApiSecureRequestThread;
begin
asr_thread := TApiSecureRequestThread.Create;
try
asr_thread.OnTerminate := ASRThreadTerminate;
asr_thread.Start;
except
asr_thread.Free;
end;
end;
procedure TfrmMain.ASRThreadTerminate(Sender: TObject);
var
asr_thread: TApiSecureRequestThread;
begin
asr_thread := Sender as TApiSecureRequestThread;
// process asr_thread.Response here
end;
end.