2011-09-21 66 views
3

覆蓋Free方法安全嗎?我在問,因爲我想用這樣的東西。我知道使用TerminateThread非常難看,但在我的情況下,立即殺死所有線程的進程非常關鍵。重寫Free方法是否安全?

我已經看到System.pas中聲明的__free方法,但我不知道它是否與TObject.Free方法有關,這就是爲什麼我詢問它是否安全的原因。

type 
    TMyThread = class(TThread) 
    private 
    destructor Destroy; override; 
    public 
    procedure Execute; override; 
    constructor Create; 
    procedure Free(const Force: Boolean = False); // is it safe to use this? 
    end; 

procedure TMyThread.Free(const Force: Boolean = False); 
begin 
    if not Force then 
    begin 
    Terminate; 
    WaitFor; 
    end 
    else 
    TerminateThread(Handle, 0); 

    inherited Free; 
end; 

destructor TMyThread.Destroy; 
begin 
    // free resources etc. 
    inherited Destroy; 
end; 

謝謝

+1

您的設計對我來說似乎不對。並且調用TerminateThread只是很糟糕。期望故障非常間歇且無法調試。期待他們出現在你最關鍵的客戶身上! –

+0

@DavidHeffernan,同意但我正在阻止WinSock套接字,並有問題。我需要在非常特殊的情況下立即關閉應用程序,並且只有在[connect](http://msdn.microsoft.com/en-us/library/ms737625%28v=VS.85%29.aspx)API函數正在處理。此功能的超時時間約爲20秒,此設置來自系統配置。我發現我可以得到意想不到的行爲,但是我們已經有了一個基於阻塞套接字的大型系統,並且確實需要立即關閉線程。 – TLama

+2

'connect()'可以通過簡單地關閉來自不同線程上下文的套接字來中止。 –

回答

10

不能覆蓋Free因爲它不是虛擬的。如果你定義了自己的Free方法,它將隱藏TObject.Free方法(注意編譯器警告),如果靜態類型是你的類類型的話。這絕對不是一個好主意,因爲對象將永遠不會被破壞。

我看不出有什麼理由要這樣做。如果你真的想要使用TerminateThread那麼只需給你的線程類別另一種方法ForceTerminate,其中你可以撥打TerminateThread

+0

感謝您的解釋。我正在考慮像'ForceTerminate'這樣的東西。無論如何,「物體永遠不會被毀壞」是真的嗎?如果我稱'繼承自由;'那麼它會或我錯了? – TLama

+0

@ michael85 - 不客氣。據我瞭解,「繼承」只有在使用覆蓋時纔有效,而不是。 – jpfollenius

+0

'繼承'調用祖先的方法,除了沒有被覆蓋的事實,所以我通過調用'inherited Free;'來真正進入'TMyThread.Destroy;'方法。當然你對「覆蓋」是正確的,這是一個錯字。使用我的設置我甚至無法編譯它,因爲錯誤消息'E2170無法重寫非虛擬方法'我只關注事實,如果它從System.pas的角度來看是安全的。 – TLama