我是新手,所以我已经尝试了几个小时(我正在使用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;
但每当我尝试编译时,我得到:
没有可以调用的'Synchronize'的重载版本 这些论点
这对我来说没有意义,因为当我从“proc”中删除“S”参数时,它工作正常。
答案 0 :(得分:14)
查看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;
答案 1 :(得分:3)
同步只需要一个无参数的程序,因为我相信你已经弄清楚了。这意味着您必须使用从主线程获得的属性才能使用它执行某些操作。例如,我的线程对象名为monitor:
Synchronize(UpdateCaption); // as called in the thread code.
procedure monitor.UpdateCaption;
// synchronize procedure for monitor thread - updates memo on form.
begin
With Form1.CommandText.Lines do
Add(TextString);
end;
或者,您可以将消息传递给主线程,但这是一种快速的方法。
答案 2 :(得分:0)
另一种方法可能是编写一个不带参数的包装函数,并在Synchronize()
中调用这个无参数的方法。