15

TListBoxなどのVCLコントロールでBeginUpdateとEndUpdateを使用すると、EndUpdateが呼び出されるまで、コントロールが再描画されないため、コントロールにItemsを設定するプロセスが高速化されることを理解しています。

例:

procedure TForm1.AddItems;
var
  i: Integer;
begin
  Screen.Cursor := crHourGlass;
  try
    for i := 0 to 5000 do
    begin
      ListBox1.Items.Add('Item' + IntToStr(i));
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

上記はリストボックスの再描画が許可されているため遅延がありますが、次のように再描画を防ぐことで遅延を短縮できます。

procedure TForm1.AddItems;
var
  i: Integer;
begin
  Screen.Cursor := crHourGlass;
  try
    ListBox1.Items.BeginUpdate;
    try
      for i := 0 to 5000 do
      begin
        ListBox1.Items.Add('Item' + IntToStr(i));
      end;
    finally
      ListBox1.Items.EndUpdate;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

次に、TStringListを使用してこれをテストしました。

procedure TForm1.AddItems;
var
  SL: TStringList;
  i: Integer;
begin
  SL := TStringList.Create;
  try
    Screen.Cursor := crHourGlass;
    try
      SL.BeginUpdate;
      try
        for i := 0 to 5000 do
        begin
          SL.Add('Item' + IntToStr(i));
        end;
      finally
        SL.EndUpdate;
      end;

      ListBox1.Items.Assign(SL);
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    SL.Free;
  end;
end;

TStringListがBegindUpdateとEndUpdateを使用しているかどうかに関係なく、リストはほぼ同じ速度で読み込まれるようです。

TStringListは視覚的にではなくメモリ内で実行されるため、これらは本当に必要ですか。とにかくTStringListでBeginUpdateとEndUpdateを使用する必要がありますが、これを行うのは良い習慣ですか?

これを尋ねるのはばかげていると思いますが、なぜTStringListにBeginUpdateとEndUpdateのプロシージャがあるのですか?

私はここで私自身の質問に答えたかもしれないと思います。どちらにしても、あなたの意見を聞きたいと思います。

ありがとう :)

4

3 に答える 3

24

BeginUpdate文字列リストのおよびOnChangingイベントOnChangeを禁止します。接続されているものによっては、物事を大幅にスピードアップすることができます。

あなたの例では、BeginUpdate/EndUpdateはあまり違いはありません。TStringlistインスタンスを使用し、それをリストビューに割り当てることは、非常に有効なアプローチです。

于 2012-02-05T16:28:12.960 に答える
10

BeginUpdateおよびEndUpdate抽象基本クラスで導入されTStringsます。したがってTStringList、特に有用ではありませんが、この機能を継承します。TStringsただし、もちろん他の多くの子孫にも役立ちます。

TStrings他の多くの子孫にはプライベート実装があることを忘れないでください。たとえば、にTStrings関連付けられたオブジェクトは、ユニットTListBoxの実装セクションにプライベートです。コントロールはアイテムリストを公開しStdCtrls、使用可能にするには、抽象基本クラスで宣言する必要があります。TListBoxTStringsBeginUpdateEndUpdate

私の見解では、あなたが知っているオブジェクトを操作するときは、これらのメソッドを安全に無視できますTStringList

さて、リストビューに入力するコードに関しては、中間を使用しても意味がありませんTStringList。リストビューに直接データを入力し、リストビューでBeginUpdate/EndUpdateを使用するだけItemsです。それでもリストビューでパフォーマンスの問題が発生する場合、解決策は仮想リストビューです。

于 2012-02-05T16:35:13.737 に答える
2

ここで説明するように、これはロックパターンの実装にすぎません。

それはあなたにあなたtemporarily lockにクラスの側面を与え、不必要な通知を避けます。

DB.TDataSet.DisableControlsおよびDB.TDataSet.EnableControlsにあるものとまったく同じです。

于 2012-02-06T10:51:28.910 に答える