2017-05-29 21 views
3

何かを描きたい。 GUIがフリーズするので、私はスレッドを描きたい。しかし時々私は図面を一時停止したい(分)。スレッドを一時停止する方法は?

サスペンド/レジュームは廃止されていますが、どの機能がそれらを置き換えるかはわかりません。

サスペンドとレジュームは推奨されていません。 SleepとSpinWaitは明らかに不適切です。私はDelphiがそのような基本的なプロパティ/機能を提供していないことに驚いています。

スレッドを一時停止/再開するにはどうすればよいですか?

+1

スレッドが定期的にチェックするフラグを設定します。その後、フラグの値に応じて描画するか、描画しません。 –

+2

イベントと 'WaitForSingleObject'を使用してください... – whosrdaddy

+0

@DavidHeffernan - ok。フラグが '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が実際のスレッド作成を 'AfterConstruction'に延期するための' TThread'のコンストラクタを修正する前に学んだ一般的なパターンです。それ以来、上記のように書く必要はありません。 –

+0

@DavidHeffernan:私は知らないが、D6以来、 "上記のような"ものは何も必要ではない? –

関連する問題