Difference between revisions of "Asynchronous Calls/ja"
m (→解決方法: Correction) |
m (Fixed syntax highlighting; deleted category already in page template) |
||
(8 intermediate revisions by 4 users not shown) | |||
Line 5: | Line 5: | ||
あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを free しなければいけないのに、後ほど親オブジェクトなどからそのオブジェクトを参照される可能性がある場合です。 | あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを free しなければいけないのに、後ほど親オブジェクトなどからそのオブジェクトを参照される可能性がある場合です。 | ||
− | |||
== 解決方法 == | == 解決方法 == | ||
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); | ||
− | + | これは、任意のメソッドを「キュー」(待ち行列)に入れ、主イベントループ(訳注 : ユーザプログラムの中にあって、ウィンドウシステムから送られてくるイベントを処理するループ。Lazarus等 では隠蔽されている)の中で、他のイベントの処理が全て終わった後で実行するようにします。その際、メソッドに任意のパラメタを渡すことができます。上の例では、free する時点では親の実行が終了していますから、free しようとしているオブジェクトへの参照は消滅しており、安全に free することができるわけです。 | |
これは [[doc:lcl/forms/tapplication.releasecomponent.html |ReleaseComponent]] の、よりジェネリックなヴァージョンであり、ReleaseComponent もこのメソッドを呼んでいることにご注意ください。 | これは [[doc:lcl/forms/tapplication.releasecomponent.html |ReleaseComponent]] の、よりジェネリックなヴァージョンであり、ReleaseComponent もこのメソッドを呼んでいることにご注意ください。 | ||
Line 22: | Line 21: | ||
次のプログラムは [[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 イベントが終了した後に実行される、という点です。 | ||
− | < | + | <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; | ||
− | |||
− | |||
− | |||
end. | end. | ||
− | </ | + | </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) │
問題について
あるイベントを処理する必要があっても、その場ですぐには処理を実行できない場合があります。例えば、オブジェクトを 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.