可能你不知道的 CPU 资源杀手

问题的提出:

如果你没有用过 TAction,或许你不该说你会 DelphiTAction 大大简化了界面逻辑的关联,加速了项目的开发。不过我在程序中大量使用 TAction 时,无意发现这样一个问题:如果程序的某个窗体里有超过100TAction,在运行这个程序时,只要不停的在该窗体上快速移动鼠标,CPU 占用率会猛增到 30% 左右。

 

为什么会有如此高的 CPU 占用?

使用 Spy++ 调试后发现,一旦鼠标快速在窗体上移动,程序会频繁发送 WM_UPDATE 消息。进一步调试后发现,TContainedAction.Update() TActionManager 频繁调用。正如帮助文档中所写:当应用程序处于空闲状态时,所有的 TxxxxAction.OnUpdate 事件会被触发。由于空闲状态频繁改变,因此 OnUpdate 也就被频繁触发,这个正是造成不当 CPU 占用的真正原因。

 
解决方案

如果你的程序中没有使用到 TxxxxAction.OnUpdate,那么你可以屏蔽 TActionManager 去查询并触发 TxxxxAction.OnUpdate。具体实现代码如下:

uses
 FastcodePatch
{http://fastcode.sourceforge.net/};

procedure TContainedActionUpdateStub;
asm
 call TContainedAction.Update;
end;

type
 TContainedActionPatch =
class(TContainedAction)
 
public
   
function Update: Boolean; override;
 
end;

function TContainedActionPatch.Update: Boolean;
begin
 Result := False;
end;

function DisableTActionOnUpdate(ActnList: TActionList): Boolean;
var
 I: Integer;
begin
 Result := True;
 
for I := 0to ActnList.ActionCount - 1do
   
if Assigned(ActnList.Actions[I].OnUpdate) then
   
begin
      Result := False;
      Break;
   
end;

 
if Result then
 
begin
    FastcodeAddressPatch(
      FastcodeGetAddress(@TContainedActionUpdateStub),
      @TContainedActionPatch.Update);
 
end;
end;


这段代码的最佳运行位置是在你程序窗体的OnCreate() 事件中。当然如果你希望彻底解决这个问题你可以修改ActnList.pas 中的TContainedAction.Update,或者提交申请让CodeGear 来改进这个问题。

 
总结

本文展示了过多使用TxxxxAction 组件可能会造成应用程序过高的CPU 占用问题。并且提供了补丁代码来解决这个问题。尽管我手上没有最新版本的 Delphi,但是估计这个问题是不会被 CodeGear 修正的。

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值