2017-02-17 4 views
5

私は、ある仕事をするスレッドを使用するプログラムを持っています。スレッドは、進行状況を別のスレッド(この例ではメインスレッド)に通知する必要があります。TThread.Queueに渡される匿名プロシージャのローカル変数の処理

私がを使用する場合、同期を実行するために()を同期すると、すべて正常に動作します。私はメインスレッドと同期とのための変数を公開し、リストに入れた場合はすべての単一の値がの正しく私のリストボックスに印刷を得る:

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Synchronize(
     procedure() 
     begin 
     FireEvent(i); 
     end); 
    end; 
end; 

出力:1、2、3、4、5。 .. 1000年

私が使用している場合はキュー()出力が期待されていないとして、同期を実行するには:

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Queue(
     procedure() 
     begin 
     FireEvent(i); 
     end); 
    end; 
end; 

出力:200、339、562、934、1001、1001、1001、1001、1001、1001、1001、1001、1001、[...]

ここで何が起きているのでしょうか?私の理解として、匿名のプロシージャは変数 "i"を取得する必要がありますか?

+0

PS:UIを頻繁に更新するのはあまり意味がありません。私は匿名のメソッドが値を取得する必要がありますが、変数の内容を変更するものを知りたいだけです。 –

+1

変数をキャプチャします。しかし、あなたは "価値"を捉えようとしています。したがって、ループの各反復ごとに1つの新しい変数を作成し、それを取得する必要があります。これには新しいスタックフレームが必要なので、関数呼び出しが必要です。これはLURDの答えのコードにつながります。 –

答えて

5

匿名プロシージャは、変数参照を取得します。 これは、匿名プロシージャの実行時に値が不定であることを意味します。

値をキャプチャするためには、次のようなユニークなフレームにそれをラップする必要があります:

Type 
    TWorkerThread = class (TThread) 
    ... 
    function GetEventProc(ix : Integer): TThreadProcedure; 
    end; 

function TWorkerThread.GetEventProc(ix : Integer) : TThreadProcedure; 
// Each time this function is called, a new frame capturing ix 
// (and its current value) will be produced. 
begin 
    Result := procedure begin FireEvent(ix); end; 
end; 

procedure TWorkerThread.Execute; 
var 
    i: Integer; 
begin 
    inherited; 

    for i := 1 to 1000 do 
    begin 
    Queue(GetEventProc(i)); 
    end; 
end; 

Anonymous methods - variable capture versus value captureを参照してください。

+0

それはコンパイルされません... –

+0

'Queue(EventWithValue(i))'と 'EventWithValue'は' TThreadProcedure'を返さなければなりません。少なくとも、それは私がやることです。 –

+0

ドキュメント[Delphiの匿名メソッド](http://docwiki.embarcadero.com/RADStudio/en/Anonymous_Methods_in_Delphi)、特に[匿名メソッドの変数バインディング](http://docwiki.embarcadero.com/RADStudio/ en/Anonymous_Methods_in_Delphi#Anonymous_Methods_Variable_Binding)。 –

関連する問題