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 :
There is no overloaded version of 'Synchronize' that can be called with these arguments
that does not make sense (to me) because when i remove the "S" parameter from "proc" it works fine.
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;
That is why passing just t.Proc
works but passing t.Proc('foo')
does not.
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;
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;
Or like this:
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;
Synchronize only takes a parameterless procedure, as I'm sure you've figured out. That means you have to use properties you get from the main thread in order to do certain things with it. For instance, my thread object is named 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;
Alternatively, you pass messages to the main thread, but this is a quick in a pinch way to do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With