2010-10-07 213 views
1

我有一個線程,爲我做一個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

更好的是什麼意思? – himself 2010-10-07 12:53:29

+0

在'正確的方式'中做得更好。然而,我從目前的答案中看到,我目前使用的方法沒有任何問題。謝謝你所有的答案。問候,彼得。 – 2010-10-07 15:12:21

回答

4

誰告訴你的?他們有任何理由嗎?

OnTerminate在執行完成之後和銷燬之前查詢線程實例。事實上,當您將TThread的FreeOnTerminate設置爲True時,您無法訪問線程的變量。

其他機制:

  • 全局變量由線程設置,查詢其他地方:呸,你仍然需要使用onterminate當線程完成就知道了。最好保留線程本身的局部變量。

  • 從線程使用PostThreadMessage:但要發佈到哪裏?這意味着讓線程知道發佈這些消息的人是誰,因此也是某種觀察者機制。

第一個我不推薦。如果你只是需要在線程終止時查詢一些值,那麼第二個恕我直言是過分的。

1

我看到這種方法沒有問題。

您存儲對線程對象的引用的唯一地方是在局部變量中,所以線程對象在運行時不可訪問。那很好;這意味着在線程完成計算它們的值之前,什麼都不能訪問線程的公共屬性或字段。

確保你釋放線程對象的某個地方。你可以通過在其構造函數中設置FreeOnTerminate屬性來實現。

+0

謝謝。我總是在線程的構造函數中設置FreeOnTerminate。 P. – 2010-10-07 15:13:36

1

我看不出你的代碼有什麼問題,哪裏不需要改進。但是如果你仍然想改進它,請注意TThread.OnTerminate代碼是在主線程的上下文中使用TThread.Syncronize執行的。這意味着你的WMIQThread進入一個等待狀態,休眠直到主線程執行TThread.OnTerminate代碼,喚醒並終止。對於只分配線程變量不需要這種同步,所以可以改進代碼,但是改進應該在TThreadWmiQuery方法中實現。

如果您不想更改TThreadWmiQuery實現,請將事情保持原樣。