加快Delphi状态栏的更新速度

发布于 2024-10-18 11:41:11 字数 273 浏览 4 评论 0原文

在 Delphi 中更新状态栏需要很长时间!

示例:我搜索文件并在状态栏中显示找到和搜索的文件数:

OwnerForm.StatusBar1.SimpleText
     := Format('Searching (%d found in %d files) ...', [NumFound, Total]);

状态栏每更新 200 次,搜索时间就会增加大约 1 秒。

有没有什么方法可以减少这种过多的开销,但仍然更新用户的状态?

Updating the status bar in Delphi takes so darn long!

Example: I search for files and display the number of files found and searched in the status bar:

OwnerForm.StatusBar1.SimpleText
     := Format('Searching (%d found in %d files) ...', [NumFound, Total]);

This adds approximately 1 second of time to the search for every 200 times the status bar is updated.

Are there any ways to reduce this excessive overhead, but still update the status for the user?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心安伴我暖 2024-10-25 11:41:11

不要这么快更新状态栏。如果您更新状态如此频繁以至于对您的性能产​​生严重影响,用户将如何读取状态?

此外,我进行了一个小测试,结果显示它在 100 多毫秒内更新了状态栏 1000 次。这是我用了 5 年的廉价家用电脑上的。

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  a: Cardinal;
begin
  a := GetTickCount;
  for i := 0 to 1000 do
  begin
    StatusBar1.SimpleText := IntToStr(i);
  end;
  ShowMessage(IntToStr(GetTickCount - a));
end;

[编辑]

替代解决方案:

  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FLastUpdate: TDateTime;
  public
    procedure UpdateStatus(Status: string);
    procedure ForceStatus(Status: string);
  end;

procedure TForm1.ForceStatus(Status: string);
begin
  StatusBar1.SimpleText := Status;
  FLastUpdate := Now;
end;

procedure TForm1.UpdateStatus(Status: string);
begin
  if MilliSecondsBetween(Now, FLastUpdate) > 500 then
  begin
    StatusBar1.SimpleText := Status;

    FLastUpdate := Now;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  a: Cardinal;
begin
  a := GetTickCount;
  for i := 0 to 1000000 do
  begin
    // unimportant: progress
    UpdateStatus(IntToStr(i));
  end;
  // Important: final state
  ForceStatus(Format('Done in %d milliseconds', [GetTickCount - a]));
end;

Don't update your status bar this fast. How will a user be able to read the status if you update it so often that it has a serious impact on your performance?

Besides I ran a little test that shows it updates the status bar a 1000 times in just over 100 ms. This is on my 5 years old cheap home pc.

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  a: Cardinal;
begin
  a := GetTickCount;
  for i := 0 to 1000 do
  begin
    StatusBar1.SimpleText := IntToStr(i);
  end;
  ShowMessage(IntToStr(GetTickCount - a));
end;

[edit]

Alternative solution:

  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FLastUpdate: TDateTime;
  public
    procedure UpdateStatus(Status: string);
    procedure ForceStatus(Status: string);
  end;

procedure TForm1.ForceStatus(Status: string);
begin
  StatusBar1.SimpleText := Status;
  FLastUpdate := Now;
end;

procedure TForm1.UpdateStatus(Status: string);
begin
  if MilliSecondsBetween(Now, FLastUpdate) > 500 then
  begin
    StatusBar1.SimpleText := Status;

    FLastUpdate := Now;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  a: Cardinal;
begin
  a := GetTickCount;
  for i := 0 to 1000000 do
  begin
    // unimportant: progress
    UpdateStatus(IntToStr(i));
  end;
  // Important: final state
  ForceStatus(Format('Done in %d milliseconds', [GetTickCount - a]));
end;
鹿港小镇 2024-10-25 11:41:11

当您在单独的线程中运行搜索时,您可以简单地使用 NumFound 和 Total 值更新一些变量。在主线程中,您可以每秒触发一次(或您喜欢的任何更新间隔)来读取此变量并更新状态栏。

由于 NumFound 和 Total 可能是整数,因此您可以使用 InterlockedXXX 函数以简单但线程安全的方式更新变量。

When you are running the search in a separate thread, you can simply update some variables with the NumFound and Total value. In the main thread you can fire a time every second (or whatever update interval you prefer) that reads this variables and updates the status bar.

As NumFound and Total probably are Integers, you can use the InterlockedXXX functions to update the variables in a simple but threadsafe way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文