我是线程的新手,所以我已经尝试了几个小时(我正在使用XE4),

我有一个简单的线程

type
  TSendThread = class(TThread)
  private
  public
    procedure proc(const s : string);
  protected
    procedure Execute; override;
  end;

  procedure TSendThread.proc(const S: String);
  begin
    showmessage(s);
  end;

现在,以我的主要形式,我想用以下命令调用该“proc”:
procedure TForm1.Button1Click(Sender: TObject);
var
  t : TSendThread;
begin
    t := TSendThread.create(true);
    t.Synchronize(nil, t.proc('foo'));
end;

但是每当我尝试编译时,我都会得到:



(对我而言)这没有意义,因为当我从“proc”中删除“S”参数时,它可以正常工作。

最佳答案

查看TThread.Synchronize()的各种声明。您正在尝试调用以TThreadMethod作为输入的版本。 TThreadMethod没有参数:

TThreadMethod = procedure of object;

这就是为什么仅传递t.Proc起作用,但不传递t.Proc('foo')的原因。

如此说来,您是完全滥用TThread.Synchronize()。您无需创建TThread对象即可使用静态版本的Synchronize()。并且如果您确实创建了TThread对象,则使其实际执行某些操作,如下所示:
type
  TSendThread = class(TThread)
  public
    fStr: String;
    procedure DoProc;
    procedure Proc(const S: string);
  protected
    procedure Execute; override;
  end;

  procedure TSendThread.Execute;
  begin
    Proc('foo');
  end;

  procedure TSendThread.Proc(const S: string);
  begin
    fStr := S;
    Synchronize(DoProc);
  end;

  procedure TSendThread.DoProc;
  begin
    ShowMessage(fStr);
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  t : TSendThread;
begin
  t := TSendThread.Create(False);
  t.WaitFor;
  t.Free;
end;

但是,由于您使用的是XE4,因此Synchronize()也支持匿名过程,这将在本示例中完全消除TSendThread类,例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TThread.Synchronize(nil,
    procedure
    begin
      ShowMessage('foo');
    end
  );
end;

更新:给定关于您真正想对线程执行的操作的新信息,您需要这样处理:
type
  TSendThread = class(TThread)
  private
    fURL, fMethod, fParam: string;
  protected
    procedure Execute; override;
  public
    constructor Create(aURL, aMethod, aParam: string);
  end;

constructor TSendThread.Create(aURL, aMethod, aParam: string);
begin
  inherited Create(False);
  fURL := aUrl;
  fMethod := aMethod;
  fParam := aParam;
end;

procedure TSendThread.Execute;
begin
  // use fURL, fMethod, and fParam as needed...
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  t : TSendThread;
begin
  t := TSendThread.Create('url', 'method', 'param');
  ...
end;

或像这样:
type
  TSendThread = class(TThread)
  private
    fURL, fMethod, fParam: string;
    procedure GetValues;
  protected
    procedure Execute; override;
  end;

procedure TSendThread.GetValues;
begin
  fURL := ...;
  fMethod := ...;
  fParam := ...;
end;

procedure TSendThread.Execute;
begin
  Synchronize(GetValues);
  // use fURL, fMethod, and fParam as needed...
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  t : TSendThread;
begin
  t := TSendThread.Create(False);
  ...
end;

关于multithreading - 传递值以同步线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16870387/

10-10 20:04