首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TAction.OnUpdate事件会降低性能吗?

TAction.OnUpdate事件会降低性能吗?
EN

Stack Overflow用户
提问于 2015-03-01 10:57:29
回答 3查看 2.2K关注 0票数 12

在Delphi XE7中,我使用此技巧根据是否选择ListView中的项自动启用或禁用工具栏按钮(“编辑ListView项”),以防止用户在没有选择ListView项的情况下单击该按钮:

  • 在VCL表单上放置一个TActionList。
  • 在ActionList中创建一个动作actTest
  • 在表单上放一个TButton。
  • 将动作actTest分配给按钮。
  • 在表单上放一个TListView。
  • 在ListView中创建两个项。
  • OnUpdate操作的actTest事件中,写:过程TForm1.actTestUpdate(发件人: TObject);begin actTest.Enabled := ListView1.SelCount > 0;CodeSite.Send('actTestUpdate');// gets经常被触发!结束;

现在您可以看到,根据是否选择了ListView中的项,该按钮将被启用或禁用,这与您是使用鼠标还是用键盘或以编程方式选择/取消选择项目无关。

但是,在CodeSite Live中,我可以看到actTestUpdate事件被连续地、经常地触发,因此actTest.Enabled := ListView1.SelCount > 0;语句经常被执行。

所以我的问题是:这会降低演出的质量吗?如果是,是否有另一种达到上述目的的伎俩?

EN

回答 3

Stack Overflow用户

发布于 2015-03-01 21:18:06

如果您有(或计划有)许多操作,您可能希望将Application.ActionUpdateDelay设置为50毫秒。这可以显著提高性能。

此外,如果您有许多操作,我建议您尝试使用TForm.UpdateActions,而不是为每个操作定义TAction.OnUpdate。它将使代码更具可读性。

票数 9
EN

Stack Overflow用户

发布于 2015-03-01 12:58:51

一般而言

是的,OnUpdate事件处理程序需要时间,就像其他例程一样。多个处理程序占用该时间的多个时间。所有这些代码的总量将评估条件,导致什么都不做。从这个意义上说,您可以得出结论,这种更新机制会降低性能。特别是考虑到这些更新事件经常发生:

在应用程序空闲或操作列表更新时发生。

这可能是不使用它的一个理由。但是,您应该认识到,对单个表达式的评估通常不会花费那么多时间。另外,请注意,不管操作更新如何,您的应用程序在每次鼠标移动时都执行(要重得多)计算和操作。

当您将代码在操作中的持续时间保持在最小的更新事件(例如,不通过数据库连接检查密码)时,性能就会显示为正常。如果您需要与更新操作相关联的冗长操作,那么在这些特定情况下返回手动更新。

请注意,如果不使用动作的单个OnUpdate事件,而是使用ActionList的OnUpdate事件(它有一个Handled参数来取消进一步的处理),就可以稍微提高性能,这将带来集中化和分类的额外好处。

具体来说

ListView1.SelCount向控件发送WinAPI消息以检索选择计数。这是一个很小的操作,我不会费心它的时间。

另一种方法是更新ListView的OnSelectItem事件中的操作。该事件将捕获由于鼠标和键盘交互以及设置各个项的Selected属性而引起的所有选择更改:

代码语言:javascript
复制
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  actTest.Enabled := ListView1.SelCount > 0;
end;

但是,ListView和VCL并不提供任何仅在SelCount = 0SelCount > 0之间发出信号的信息,因此无论如何,您将对这一行代码进行更多的评估,而不是绝对必要的代码。

假设MultiSelect为真,您也可以自己计算选择更改,以消除调用SelCount的需要

代码语言:javascript
复制
  private
    FListViewSelected: Longbool;

procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  if Selected then
    Inc(FListViewSelected)
  else
    Dec(FListViewSelected);
  actTest.Enabled := FListViewSelected;
end;

或测试所选项目为零:

代码语言:javascript
复制
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  actTest.Enabled := ListView1.Selected <> nil;
end;

但是,没有理由不使用OnUpdate事件:

代码语言:javascript
复制
procedure TForm1.ActionList1Update(Action: TBasicAction; var Handled: Boolean);
begin
  actTest.Enabled := ListView1.Selected <> nil;
  Handled := True;
end;
票数 5
EN

Stack Overflow用户

发布于 2015-03-01 11:17:58

Action事件(主要是在Application.Idle中执行)。只要您不在事件处理程序中做时间关键的事情,就不会出现明显的性能下降。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28792745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档