我有一个为我做WMI查询的线程,我需要在执行查询后访问线程中的一些变量。
线程创建如下......
procedure TFormMain.RunThread;
var
WMIQ: TThreadWmiQuery;
begin
WMIQ := TThreadWmiQuery.Create(True);
...
WMIQ.OnTerminate := WMIQThreadOnTerminate;
WMIQ.Resume;
end;
在OnTerminate事件中,我得到了我需要的值......
procedure TFormMain.WMIQThreadOnTerminate(Sender: TObject);
begin
Opcd := TThreadWmiQuery(Sender).P4COpcd;
Role := TThreadWmiQuery(Sender).P4CRole;
Usnm := TThreadWmiQuery(Sender).P4CUsnm;
end;
我被告知这可能不是访问线程变量的最佳方法。还有其他更好的方法,我可以轻松地从我的线程中获取数据而不会有太多的复杂性吗?
问候,彼得
答案 0 :(得分:4)
谁告诉过你的?他们有任何理由吗?
OnTerminate用于在线程实例执行完毕之后和销毁之前查询它。事实上,当你将TThread的FreeOnTerminate设置为True时,你没有其他地方可以访问线程的变量。
其他机制:
由线程设置的全局变量,在别处查询:yuck,你仍然需要使用onterminate来知道线程何时完成。最好将变量保持在线程本身的本地。
使用帖子中的PostThreadMessage:但是要发布到哪里?这意味着让线程知道发布这些消息的人,以及某种观察者机制。
第一个我不推荐。如果你只需要在线程终止时查询几个值,那么第二个恕我直言就太过分了。
答案 1 :(得分:1)
我认为这种方法没有问题。
存储对线程对象的引用的唯一位置是局部变量,因此线程对象在运行时无法访问。非常好;这意味着在线程完成计算其值之前,没有任何东西可以访问线程的公共属性或字段。
确保在某处释放线程对象。您可以通过在其构造函数中设置其FreeOnTerminate
属性来实现此目的。
答案 2 :(得分:1)
我的代码中没有看到任何错误,无需改进代码。但是如果您仍想改进它,请注意使用TThread.Syncronize在主线程的上下文中执行TThread.OnTerminate代码。这意味着你的WMIQThread进入等待状态,一直睡到主线程执行TThread.OnTerminate代码,唤醒并终止。只需分配线程变量就不需要这样的同步,因此可以改进代码,但是应该在TThreadWmiQuery方法中实现改进。
如果您不想更改TThreadWmiQuery实现,请保留原样。