Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading TThread执行的结果_Multithreading_Delphi - Fatal编程技术网

Multithreading TThread执行的结果

Multithreading TThread执行的结果,multithreading,delphi,Multithreading,Delphi,这段代码似乎不是获取线程结果的正确方法,即使表单没有冻结,我也可以执行不同的其他任务,可能是其他请求,因此线程的数量不会一直等于一个,可能同时有多达5个请求,但并不相互依赖 如何以“良好”的方式做到这一点 不要使用Application.ProcessMessages。这是一个糟糕的代码设计示例,您应该避免使用它 相反,使用线程回调或消息。例如: uAPISecureRequestThread.pas unit uAPISecureRequestThread; interface uses

这段代码似乎不是获取线程结果的正确方法,即使表单没有冻结,我也可以执行不同的其他任务,可能是其他请求,因此线程的数量不会一直等于一个,可能同时有多达5个请求,但并不相互依赖

如何以“良好”的方式做到这一点


不要使用
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答案的最后一条评论,看看我发明的解决方法。