Multithreading TThread执行的结果
这段代码似乎不是获取线程结果的正确方法,即使表单没有冻结,我也可以执行不同的其他任务,可能是其他请求,因此线程的数量不会一直等于一个,可能同时有多达5个请求,但并不相互依赖 如何以“良好”的方式做到这一点Multithreading TThread执行的结果,multithreading,delphi,Multithreading,Delphi,这段代码似乎不是获取线程结果的正确方法,即使表单没有冻结,我也可以执行不同的其他任务,可能是其他请求,因此线程的数量不会一直等于一个,可能同时有多达5个请求,但并不相互依赖 如何以“良好”的方式做到这一点 不要使用Application.ProcessMessages。这是一个糟糕的代码设计示例,您应该避免使用它 相反,使用线程回调或消息。例如: uAPISecureRequestThread.pas unit uAPISecureRequestThread; interface uses
不要使用
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.
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.
umaninform.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.
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.
不要使用
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.
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.
umaninform.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.
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.
在一个函数中无法实现这一点,对吗?我已经考虑过了,当线程退出时,调用函数。但这将导致回调处理程序中出现大量代码,例如该线程做了什么,用户为什么要这样做,我们应该如何处理响应。。我的意思是,请求和响应之间没有直接的联系。而试图实现此API驱动程序的用户必须关心其表单中的所有回调。。。总之,所有这些都引出了这个评论的第一个问题。我知道的那个问题,不是。你可以检查
OmniThreadLibrary
或其他一些线程库,但我不确定是否有某种机制可以在单个函数调用中实现这一点。它超越了线程的目的。Omni有Async
构造,这可能很有用,但不能将其视为C#4.5 Async/Await构造的等价物。异常吞咽器是dubious@Goover:如果您想使用线程,但仍然只有一个函数等待结果,那么根本不要使用线程。但如果必须这样做,那么至少将等待循环改为使用MsgWaitForMultipleObjects()
。这不仅会告诉您线程何时终止,还会告诉您何时调用Application.ProcessMessages()
。在一个函数中无法做到这一点,对吗?我已经考虑过了,当线程退出时,调用函数。但这将导致回调处理程序中出现大量代码,例如该线程做了什么,用户为什么要这样做,我们应该如何处理响应。。我的意思是,请求和响应之间没有直接的联系。而试图实现此API驱动程序的用户必须关心其表单中的所有回调。。。总之,所有这些都引出了这个评论的第一个问题。我知道的那个问题,不是。你可以检查OmniThreadLibrary
或其他一些线程库,但我不确定是否有某种机制可以在单个函数调用中实现这一点。它超越了线程的目的。Omni有Async
构造,这可能很有用,但不能将其视为C#4.5 Async/Await构造的等价物。异常吞咽器是dubious@Goover:如果您想使用线程,但仍然只有一个函数等待结果,那么根本不要使用线程。但如果必须这样做,那么至少将等待循环改为使用MsgWaitForMultipleObjects()
。这不仅会告诉您线程何时终止,还会告诉您何时调用Application.ProcessMessages()
。您完全无法从一开始就创建线程。如果要在处阻止TEApi.FApiRequest
,而(不是RequestThread.Terminated)do
,那么创建线程就没有意义了。就在你现在的地方工作吧。线程的关键是创建并启动它,然后让它在同时做其他事情的同时完成它的工作。@Craigyong,是的,我明白这一点。在我的例子中,创建线程的重点是长时间工作的TIDHTTP.Post
请求,它冻结了表单,而没有任何可能将应用程序.ProcessMessages
行放入其中,因此我创建了一个线程,只是为了在处理请求时让表单工作。你可以阅读我对Marko Paunovic答案的最后一条评论,看看我发明了一个变通方法。你完全没有在一开始就创建线程。如果要在处阻止TEApi.FApiRequest
,而(不是RequestThread.Terminated)do
,那么创建线程就没有意义了。就在你现在的地方工作吧。线程的关键是创建并启动它,然后让它在同时做其他事情的同时完成它的工作。@Craigyong,是的,我明白这一点。在我的例子中,创建线程的重点是长时间工作的TIDHTTP.Post
请求,它冻结了表单,而没有任何可能将应用程序.ProcessMessages
行放入其中,因此我创建了一个线程,只是为了在处理请求时让表单工作。你可以阅读我对Marko Paunovic答案的最后一条评论,看看我发明的解决方法。