2017-05-29 71 views
3

我想畫一些東西。由於GUI凍結,我想繪製一個線程。但有時我想暫停繪圖(幾分鐘)。如何暫停一個線程?

德爾福的文檔說暫停/恢復已過時,但不知道哪些功能替代它們。

暫停和恢復已棄用。 Sleep和SpinWait顯然不合適。我很驚訝地發現Delphi不提供這樣一個基本的屬性/特性。

那麼,我該如何暫停/恢復一個線程?

+1

您設置了一個您的線程定期檢查的標誌。然後根據標誌的值繪製或不繪製。 –

+2

使用事件和'WaitForSingleObject' ... – whosrdaddy

+0

@DavidHeffernan - 好的。當標誌是'DoNotDraw'時,我用什麼來暫停線程? THread.Sleep(100)是一個好主意? – Ampere

回答

6

您可能需要通過關鍵部分的fPaused/fEvent保護。這取決於你的具體實現。

interface 

uses 
    Classes, SyncObjs; 

type 
    TMyThread = class(TThread) 
    private 
    fEvent: TEvent; 
    fPaused: Boolean; 
    procedure SetPaused(const Value: Boolean); 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(const aPaused: Boolean = false); 
    destructor Destroy; override; 

    property Paused: Boolean read fPaused write SetPaused; 
    end; 

implementation 

constructor TMyThread.Create(const aPaused: Boolean = false); 
begin 
    fPaused := aPaused; 
    fEvent := TEvent.Create(nil, true, not fPaused, ''); 
    inherited Create(false); 
end; 

destructor TMyThread.Destroy; 
begin 
    Terminate; 
    fEvent.SetEvent; 
    WaitFor; 
    fEvent.Free; 
    inherited; 
end; 

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    begin 
    fEvent.WaitFor(INFINITE); 
    // todo: your drawings here 
    end; 
end; 

procedure TMyThread.SetPaused(const Value: Boolean); 
begin 
    if (not Terminated) and (fPaused <> Value) then 
    begin 
    fPaused := Value; 
    if fPaused then 
     fEvent.ResetEvent else 
     fEvent.SetEvent; 
    end; 
end; 
+1

應該不是繼承構造函數的開始而是結束的時候? –

+1

這是在Delphi 6修復'TThread'構造函數推遲實際線程創建到'AfterConstruction'之前學習的一種常見模式。從那時起,沒有必要像上面那樣寫出來。 –

+0

@DavidHeffernan:請原諒我不知道,但自從D6以來,「以上」的內容沒有必要嗎? –