I'd like to subclass TThread
in order to have a thread class that, when FreeOnTerminate = True
, sets to nil
its reference variable.
In other words, I want do do something like this:
TFreeAndNilThread = class(TThread)
private
FReferenceObj: TFreeAndNilThread; //?? // <-- here I'm holding the reference to myself
protected
procedure Execute;
procedure DoTerminate; override; // <-- here I'll set FReferenceObj to nil after inherited (only if FreeAndNil = True)
public
constructor Create(CreateSuspended: Boolean; var ReferenceObj); reintroduce; <-- untyped param like FreeAndNil and TApplication.CreateForm ??
end;
The consumer code should be like this:
var
MyThread: TFreeAndNilThread;
begin
MyThread := TFreeAndNilThread.Create(True, MyThread);
MyThread.FreeOnTerminate := True;
MyThread.Resume;
end;
...and then I could safely test for Assigned(MyThread)
.
I see how FreeAndNil
manages to set a reference object passed by untyped param to nil
, but it does this locally.
In my case I should "save" it to a class field (FReferenceObj
) and make it nil in another place (DoTerminate
).
How can I correctly pass, store and retrieve it? I can think of passing and storing the address of MyThread instead of MyThread itself, but I hope there is a more elegant way.
Thank you!
You need to store a pointer to the variable.
Then you need to pass in the reference in the constructor:
Then you can implement it like this:
When the thread dies you set the reference to
nil
like this:For convenience, since you'd likely treat this as a base class from which you derive other classes, you may prefer to make the parameter to the constructor untyped. You can just do that without making other changes to the code. When you do so the constructor looks like this:
This will only do you good if the code that sets the reference to
nil
is in the same thread as all other code that attempts to referenceMyThread
. Otherwise you will have a race condition.I'm fairly sure that your idea is not the solution to your problem. However, the above does show you how to take a reference to a variable, which is what you asked for.