Difference between revisions of "Asynchronous Calls/ja"

From Lazarus wiki
Jump to navigationJump to search
m (→‎問題について: translation error correction)
m (Fixed syntax highlighting; deleted category already in page template)
 
(10 intermediate revisions by 4 users not shown)
Line 5: Line 5:
  
 
あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを free しなければいけないのに、後ほど親オブジェクトなどからそのオブジェクトを参照される可能性がある場合です。
 
あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを free しなければいけないのに、後ほど親オブジェクトなどからそのオブジェクトを参照される可能性がある場合です。
(日本語訳注:関連記事=http://lazarus-dev.blogspot.com/2008/01/new-0926-features-part-1-sendmessage.html )
 
  
 
== 解決方法 ==
 
== 解決方法 ==
Line 15: Line 14:
 
  procedure [[doc:lcl/forms/tapplication.queueasynccall.html |QueueAsyncCall]](AMethod: TDataEvent; Data: PtrInt);
 
  procedure [[doc:lcl/forms/tapplication.queueasynccall.html |QueueAsyncCall]](AMethod: TDataEvent; Data: PtrInt);
 
   
 
   
This will "queue" the given method with the given parameter for execution in the main event loop, when all other events have been processed. In the example above, the reference to the object you wanted to free has gone, since the then-parent has finished execution, and the object you wanted to free can be freed safely.
+
これは、任意のメソッドを「キュー」(待ち行列)に入れ、主イベントループ(訳注 : ユーザプログラムの中にあって、ウィンドウシステムから送られてくるイベントを処理するループ。Lazarus等 では隠蔽されている)の中で、他のイベントの処理が全て終わった後で実行するようにします。その際、メソッドに任意のパラメタを渡すことができます。上の例では、free する時点では親の実行が終了していますから、free しようとしているオブジェクトへの参照は消滅しており、安全に free することができるわけです。
  
Note that this is a more generic version of [[doc:lcl/forms/tapplication.releasecomponent.html |ReleaseComponent]], and ReleaseComponent calls this method.
+
これは [[doc:lcl/forms/tapplication.releasecomponent.html |ReleaseComponent]] の、よりジェネリックなヴァージョンであり、ReleaseComponent もこのメソッドを呼んでいることにご注意ください。
  
 
== 例 ==
 
== 例 ==
  
 
次のプログラムは [[doc:lcl/forms/tapplication.queueasynccall.html |QueueAsyncCall]] の使い方を示しています。 CallButton を押すと、'Click 1', 'Click 2' そして 'Async 1' が LogListBox に追加されます。注目すべきところは、Async メソッドは、CallButtonClick イベントが終了した後に実行される、という点です。
 
次のプログラムは [[doc:lcl/forms/tapplication.queueasynccall.html |QueueAsyncCall]] の使い方を示しています。 CallButton を押すと、'Click 1', 'Click 2' そして 'Async 1' が LogListBox に追加されます。注目すべきところは、Async メソッドは、CallButtonClick イベントが終了した後に実行される、という点です。
<pre>
+
<syntaxhighlight lang="pascal">
 
unit TestQueueAsyncCall;
 
unit TestQueueAsyncCall;
  
Line 53: Line 52:
  
 
implementation
 
implementation
 +
 +
{$R *.lfm}
  
 
{ TQueueAsyncCallForm }
 
{ TQueueAsyncCallForm }
Line 68: Line 69:
 
   LogListBox.Items.Add('Async '+ IntToStr(Data));
 
   LogListBox.Items.Add('Async '+ IntToStr(Data));
 
end;
 
end;
 
initialization
 
  {$I testqueueasynccall.lrs}
 
  
 
end.
 
end.
 
                                                                                              
 
                                                                                              
</pre>
+
</syntaxhighlight>
 +
 
 +
==関連項目==
 +
 
 +
* [http://lazarus-dev.blogspot.com/2008/01/new-0926-features-part-1-sendmessage.html New 0.9.26 features. Part 1. SendMessage and PostMessage]
 +
* [[Main Loop Hooks]]
 +
* [[Multithreaded Application Tutorial/ja|マルチスレッドアプリケーションチュートリアル]]

Latest revision as of 09:59, 9 February 2020

English (en) français (fr) 日本語 (ja) русский (ru)

日本語版メニュー
メインページ - Lazarus Documentation日本語版 - 翻訳ノート - 日本語障害情報

問題について

あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを free しなければいけないのに、後ほど親オブジェクトなどからそのオブジェクトを参照される可能性がある場合です。

解決方法

Application.QueueAsyncCall メソッドを使用してください。

TDataEvent = procedure (Data: PtrInt) of object;

procedure QueueAsyncCall(AMethod: TDataEvent; Data: PtrInt);

これは、任意のメソッドを「キュー」(待ち行列)に入れ、主イベントループ(訳注 : ユーザプログラムの中にあって、ウィンドウシステムから送られてくるイベントを処理するループ。Lazarus等 では隠蔽されている)の中で、他のイベントの処理が全て終わった後で実行するようにします。その際、メソッドに任意のパラメタを渡すことができます。上の例では、free する時点では親の実行が終了していますから、free しようとしているオブジェクトへの参照は消滅しており、安全に free することができるわけです。

これは ReleaseComponent の、よりジェネリックなヴァージョンであり、ReleaseComponent もこのメソッドを呼んでいることにご注意ください。

次のプログラムは QueueAsyncCall の使い方を示しています。 CallButton を押すと、'Click 1', 'Click 2' そして 'Async 1' が LogListBox に追加されます。注目すべきところは、Async メソッドは、CallButtonClick イベントが終了した後に実行される、という点です。

unit TestQueueAsyncCall;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
  StdCtrls;

type

  { TQueueAsyncCallForm }

  TQueueAsyncCallForm = class(TForm)
    CallButton: TButton;
    LogListBox: TListBox;
    procedure CallButtonClick(Sender: TObject);
  private
    { private declarations }
    FCounter: PtrInt;
    procedure Async(Data: PtrInt);
  public
    { public declarations }
  end; 

var
  QueueAsyncCallForm: TQueueAsyncCallForm;

implementation

{$R *.lfm}

{ TQueueAsyncCallForm }

procedure TQueueAsyncCallForm.CallButtonClick(Sender: TObject);
begin
  LogListBox.Items.Add('Click 1');
  FCounter := FCounter+1;
  Application.QueueAsyncCall(@Async,FCounter);
  LogListBox.Items.Add('Click 2');
end;

procedure TQueueAsyncCallForm.Async(Data: PtrInt);
begin
   LogListBox.Items.Add('Async '+ IntToStr(Data));
end;

end.

関連項目