TThreadListとは
TThreadListは、TListのスレッドセーフなラッパーです。
項目の追加と削除
項目の追加や削除を行うメソッドはスレッドセーフです。
//項目をリストの最後に追加します。
procedure Add(const Item: T);
//リストのすべての項目を削除します。
procedure Clear;
//項目の最初の出現箇所を削除します
procedure Remove(const Item: T);
//指定された方向にループ処理して、最初に見つかった項目を削除します。
procedure RemoveItem(const Item: T; Direction: TDirection);
サンプルコード
uses System.Generics.Collections;
ThreadList := TThreadList<string>.Create;
//追加や削除はメソッドを呼び出すだけ
ThreadList.Add('Delphi');
ThreadList.Add('C++Builder');
ThreadList.Add('RAD Studio');
ThreadList.Add('HTML5 Builder');
ThreadList.Remove('HTML5 Builder');
リストの項目を操作する
リストの項目を取得したり変更するときは、LockListメソッドでリストをロックします。
作業が終わったら、UnlockListメソッドを呼び出して、ロックを解除します。
サンプルコード
procedure TForm1.Print(ThreadList: TThreadList<string>);
var
List: TList<string>;
S: string;
begin
try
// リストの要素に操作するときはリストをロックする
List := ThreadList.LockList;
// リストをロックしてから要素を操作する
for S in List do
begin
Memo1.Lines.Add(S);
end;
finally
// 処理が終わったらロックを解除する
ThreadList.UnlockList;
end;
ThreadList.Free;
end;
リストの項目の変更を知るには
リストの項目の変更を知るには、TThreadListが所有するTListのOnNotifyイベントを使用します。
サンプルコード
リストの項目が変更されたときに呼び出されるイベントを作成します。
type
TForm1 = class(TForm)
…
private
{ private 宣言 }
/// <summary>
/// リストの項目が変更されたときに呼び出されるイベント
/// </summary>
procedure OnListNofity(Sender: TObject; const Item: string;
Action: System.Generics.Collections.TCollectionNotification);
…
end;
procedure TForm1.OnListNofity(Sender: TObject; const Item: string;
Action: System.Generics.Collections.TCollectionNotification);
begin
case Action of
cnAdded: // エントリがリストに追加された
Memo1.Lines.Add('追加:' + Item);
cnRemoved: // エントリがリストから削除された
Memo1.Lines.Add('削除:' + Item);
cnExtracted: // エントリがリストから抽出された
Memo1.Lines.Add('抽出:' + Item);
end;
end;
イベントを設定します。
ThreadList := TThreadList<string>.Create;
List := ThreadList.LockList;
List.OnNotify := Self.OnListNofity;
ThreadList.UnlockList;
サンプルアプリケーション
次のアプリケーションはリストの項目が変更されたときと、リストの項目をメモコンポーネント委に表示します。
Delphi XE3/XE5/XE6で確認しています。
FireMonkeyデスクトップアプリケーション→HD FireMonkeyアプリケーションを作成します。
フォームにボタンコンポーネントとメモコンポーネントを配置します。
usesに「System.Generics.Collections」を追加します。
リストの項目が変更されたときに呼び出されるprivateメソッドを追加します。
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
private
{ private 宣言 }
/// <summary>
/// リストの項目が変更されたときに呼び出されるイベント
/// </summary>
procedure OnListNofity(Sender: TObject; const Item: string;
Action: System.Generics.Collections.TCollectionNotification);
public
{ public 宣言 }
end;
procedure TForm1.OnListNofity(Sender: TObject; const Item: string;
Action: System.Generics.Collections.TCollectionNotification);
begin
case Action of
cnAdded: // 項目がリストに追加された
Memo1.Lines.Add('追加:' + Item);
cnRemoved: // 項目がリストから削除された
Memo1.Lines.Add('削除:' + Item);
cnExtracted: // 項目がリストから抽出された
Memo1.Lines.Add('抽出:' + Item);
end;
end;
ボタンのOnClickイベントを追加します。
procedure TForm1.Button1Click(Sender: TObject);
var
ThreadList: TThreadList<string>;
List: TList<string>;
S: string;
begin
ThreadList := TThreadList<string>.Create;
List := ThreadList.LockList;
// 項目が変更されたときに呼び出されるイベントを設定する
List.OnNotify := Self.OnListNofity;
ThreadList.UnlockList;
ThreadList.Add('Delphi'); // 追加
ThreadList.Add('C++Builder'); // 追加
ThreadList.Add('RAD Studio'); // 追加
ThreadList.Add('HTML5 Builder'); // 追加
ThreadList.Remove('HTML5 Builder'); // 削除
List := ThreadList.LockList;
List.Items[2] := 'RAD Studio XE6'; // 置換
// 項目の表示
for S in List do
begin
Memo1.Lines.Add('要素:' + S);
end;
ThreadList.UnlockList;
// クリア
ThreadList.Clear;
ThreadList.Free;
end;
アプリケーションを実行します。
リストの項目の状態が表示されました。
C++ Builder XE4 Firemonkey HD App. では動かないようです。
何か不具合があるのかもしれませんね。
Embarcadero Discussion Forumsで質問してみたら情報を得られるかもしれません。
https://forums.embarcadero.com/forum.jspa?forumID=13