本文介绍了传递值来同步线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的线程,所以我一直在尝试几个小时(我使用XE4),

I'm new to thread, so i've been trying with this for hours (i'm using XE4),

我有一个简单的线程



i have a simple thread

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;

现在,以我的主要形式,我想用

Now, in my main form, i want to call that "proc" with :

procedure TForm1.Button1Click(Sender: TObject);
var
  t : TSendThread;
begin
    t := TSendThread.create(true);
    t.Synchronize(nil, t.proc('foo'));
end;

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

But whenever i try t compile that i get :

对我来说没有意义,因为当我从proc中删除S参数时,它工作正常。

that does not make sense (to me) because when i remove the "S" parameter from "proc" it works fine.

推荐答案

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

Look at the various declarations of TThread.Synchronize(). You are trying to call the version that takes a TThreadMethod as input. TThreadMethod is parameter-less:

TThreadMethod = procedure of object;

这就是为什么只传递 t.Proc 作品,但通过 t.Proc('foo')不。

That is why passing just t.Proc works but passing t.Proc('foo') does not.

就是说,你是完全滥用 TThread.Synchronize()。您不需要创建一个 TThread 对象,以便使用静态版本的 Synchronize()。如果您创建一个 TThread 对象,请使其实际执行某些操作,如下所示:

With that said, you are completely misusing TThread.Synchronize(). You don't need to create a TThread object in order to use the static version of Synchronize(). And if you do create a TThread object, make it actually do something, like this:

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 类,例如:

However, because you are using XE4, Synchronize() also supports anonymous procedures as well, which would eliminate your TSendThread class completely in this example, eg:

procedure TForm1.Button1Click(Sender: TObject);
begin
  TThread.Synchronize(nil,
    procedure
    begin
      ShowMessage('foo');
    end
  );
end;

更新:给出关于您真正想要做什么的新信息线程,你需要像这样改为:

Update: given new info about what you REALLY want to do with your thread, you need to go about it like this instead:

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;

这篇关于传递值来同步线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 06:22