views:

85

answers:

3

I have a thread that does a WMI query for me and I need to access some variables in the thread after it has executed the query.

The thread is created as follows ...

procedure TFormMain.RunThread;
var
  WMIQ: TThreadWmiQuery;
begin
  WMIQ := TThreadWmiQuery.Create(True);
  ...
  WMIQ.OnTerminate := WMIQThreadOnTerminate;
  WMIQ.Resume;
end;

and in the OnTerminate event I get the values I need like so ...

procedure TFormMain.WMIQThreadOnTerminate(Sender: TObject);
begin
  Opcd := TThreadWmiQuery(Sender).P4COpcd;
  Role := TThreadWmiQuery(Sender).P4CRole;
  Usnm := TThreadWmiQuery(Sender).P4CUsnm;
end;

I've been told that this may not the best way to access the thread variables. Is there any other, better, ways I can easily get data from my thread without too much complexity?

Regards, Pieter

+1  A: 

I see no problem with that approach.

The only place you store a reference to the thread object is in a local variable, so the thread object is inaccessible while it's running. That's good; it means nothing can access the thread's public properties or fields until the thread has finished calculating their values.

Make sure you free the thread object somewhere. You could do that by setting its FreeOnTerminate property in its constructor.

Rob Kennedy
Thanks. I always set the FreeOnTerminate in the constructor of the thread. P.
Pieter van Wyk
+3  A: 

Who told you that? Did they give any reasons?

OnTerminate is there to query a thread instance after it has finished executing and before it is destroyed. In fact, when you set TThread's FreeOnTerminate to True, you have no other place to access the thread's variables.

Other mechanisms:

  • global variable set by the thread, queried elsewhere : yuck and you would still need to use onterminate to know when the thread is finished. Better to keep the variables local to the thread itself.

  • using PostThreadMessage from the thread: but where to post to? That would mean letting the thread know to whom to post these message and thus some kind of an observer mechanism.

The first I'd not recommend. The second IMHO is overkill if you just need to query a couple of values upon thread termination.

Marjan Venema
+1  A: 

I don't see anything wrong in your code, where is no need to improve it. But if you still want to improve it make notice that TThread.OnTerminate code is executed in the context of main thread using TThread.Syncronize. That means that your WMIQThread enters a wait state, sleeps until the main thread executed TThread.OnTerminate code, wakes up and terminates. There is no need for such a synchronization for just assigning thread variables, so the code may be improved, but the improvement should be implemented in TThreadWmiQuery methods.

If you don't want to change TThreadWmiQuery implementation just leave the things as is.

Serg