2017-05-29 92 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以来,“以上”的内容没有必要吗? –