2013年9月14日土曜日

TThreadList.Duplicates は dupIgnore

TStringList も TThreadList も Duplicates の型は同じです。

TDuplicates = (dupIgnore, dupAccept, dupError);

(Delphi とは順番が違いますが、先頭は同じなので default 指定や、コンストラクタ等で値が設定されていなければ dupIgnore になります)

dupIgnore は同じ値を追加しようとしても無視されて追加されません。

しかし、 TStringList は Sorted=True にしないと、dupIgnore が機能しません。

なので

Duplicates が dupIgnore のままであっても

sl:=TStringList.Create;
sl.Add('A');
sl.Add('A');
sl.Add('A');

とやると

sl.Count = 3 です。


sl:=TStringList.Create;
sl.Sorted:=True;
sl.Add('A');
sl.Add('A');
sl.Add('A');

とすれば

sl.Count = 1 です。

問題なのは TThreadList で、Duplicates のデフォルトは同じように dupIgnore になっています。
Sorted プロパティなどは無く、インスタンス作成直後から同じ値が追加されない仕様です。

TThreadList で、オブジェクトのインスタンスなどを管理する場合は、毎回異なる値が追加されるので問題ありませんが、その他の目的で利用しようと思う場合は注意が必要です。

obj:= TTest.Create;
lst:= TThreadList.Create;
lst.Add(obj1);
lst.Add(obj1);
lst.Add(obj1);

with lst.LockList do
try
  OutPutDebugString(PChar(IntToStr(Count))
finally
  lst.UnlockList;
end;

イベントログに表示される Count は 1 です。

なので、重複を許可したい場合は、インスタンス作成後に Duplicates:= dupAccept に設定するのを忘れないようにしないといけません。

lst:= TThreadList.Create;
lst.Duplicates:= dupAccept;
lst.Add(obj1);
lst.Add(obj1);
lst.Add(obj1);

with lst.LockList do
try
  OutPutDebugString(PChar(IntToStr(Count))
finally
  lst.UnlockList;
end;

イベントログに表示される Count は 3 です。

ということを忘れたまま、オブジェクトのスタック的なものを実装しようとしているとハマってしまいますのでご注意あれ。

ちなみに TList は Duplicates プロパティはありません。


FPC も Delphi も同じです。

0 件のコメント:

コメントを投稿