クライアント/サーバーデータ交換ごとにスレッドクラスを作成することによって課せられるオーバーヘッドを回避したい場合は、次のように動作可能なスレッドクラスを作成できます。
http://delphidicas.blogspot.com/2008/08/anonymous-methods-when-should-they-be.html
数日前に同じ問題が発生し、D2009の新しい匿名メソッド機能を使用してスレッドを作成できる静的関数を持つクラスTMotileThreadingを作成しました。次のようになります。
type
TExecuteFunc = reference to procedure;
TMotileThreading = class
public
class procedure Execute (Func : TExecuteFunc);
class procedure ExecuteThenCall (Func : TExecuteFunc; ThenFunc : TExecuteFunc);
end;
2番目の手順では、あなたの場合のようにクライアント/サーバー通信を実行し、データが到着するたびにいくつかの処理を実行できます。匿名メソッドの良いところは、呼び出し元のコンテキストのローカル変数を使用できることです。したがって、通信は次のようになります。
var
NewData : String;
begin
TMotileThreading.ExecuteThenCall (
procedure
begin
NewData := IdTCPClient.IOHandler.Readln;
end,
procedure
begin
GUIUpdate (NewData);
end);
end;
ExecuteメソッドとExecuteThenCallメソッドは、ワーカースレッドを作成し、FreeOnTerminateをtrueに設定するだけで、メモリ管理を簡素化し、ワーカースレッドのExecuteおよびOnTerminateプロシージャで提供される関数を実行します。
お役に立てば幸いです。
編集(クラスTMotileThreadingの完全な実装の要求に応じて)
type
TExecuteFunc = reference to procedure;
TMotileThreading = class
protected
constructor Create;
public
class procedure Execute (Func : TExecuteFunc);
class procedure ExecuteAndCall (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean = False);
end;
TMotile = class (TThread)
private
ExecFunc : TExecuteFunc;
TerminateHandler : TExecuteFunc;
SyncTerminateHandler : Boolean;
public
constructor Create (Func : TExecuteFunc); overload;
constructor Create (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean); overload;
procedure OnTerminateHandler (Sender : TObject);
procedure Execute; override;
end;
implementation
constructor TMotileThreading.Create;
begin
Assert (False, 'Class TMotileThreading shouldn''t be used as an instance');
end;
class procedure TMotileThreading.Execute (Func : TExecuteFunc);
begin
TMotile.Create (Func);
end;
class procedure TMotileThreading.ExecuteAndCall (Func : TExecuteFunc;
OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean = False);
begin
TMotile.Create (Func, OnTerminateFunc, SyncTerminateFunc);
end;
constructor TMotile.Create (Func : TExecuteFunc);
begin
inherited Create (True);
ExecFunc := Func;
TerminateHandler := nil;
FreeOnTerminate := True;
Resume;
end;
constructor TMotile.Create (Func : TExecuteFunc; OnTerminateFunc : TExecuteFunc;
SyncTerminateFunc : Boolean);
begin
inherited Create (True);
ExecFunc := Func;
TerminateHandler := OnTerminateFunc;
SyncTerminateHandler := SyncTerminateFunc;
OnTerminate := OnTerminateHandler;
FreeOnTerminate := True;
Resume;
end;
procedure TMotile.Execute;
begin
ExecFunc;
end;
procedure TMotile.OnTerminateHandler (Sender : TObject);
begin
if Assigned (TerminateHandler) then
if SyncTerminateHandler then
Synchronize (procedure
begin
TerminateHandler;
end)
else
TerminateHandler;
end;