Don’t you love relevant documentation…
There is no unit defined for the Vcl.Forms.TApplication.ActionUpdateDelay – RAD Studio API Documentation.
It is used inside the TAppliation.Idle to fire the (undocumented) TApplication.DoActionIdle method. When the value is zero or less, then each Idle call will result in an DoActionIdle call in turn calling TCustomForm.UpdateActions for any visible form.
UpdateActions in turn will call (for the form itself, all the form’s menu items and all the form’s controls) the TControl.InitiateAction which – if there is an associated ActionLink – will call the TBasicActionLink.Update which in turn will call the TBasicAction.Suspended and TBasicAction.Update methods of which the latter will call the TBasicAction.OnUpdate event if it is assigned.
In theory, the OnUpdate method for each action can even be called multiple times (because multiple controls on visible forms can point to it), but the real culprit is that TApplication.Idle as it can be called from these places:
- TApplication.DoApplicationIdle
- TApplication.HandleMessage (in a loop from TApplication.Run)
- TCustomActionMenuBar.ProcessMenuLoop (in a loop)
- TCustomRibbon.DisplayKeyTips (in a loop)
The last three (especially HandleMessage) can be disastrous as they can be called a lot (for instance when moving the mouse), and more often than not, the OnUpdate event handlers aren’t exactly CPU friendly.
A while ago I bumped into an application where the OnUpdate event handler for one action was called half a million time in under 5 minutes.
This clearly indicated a huge problem (besides using a full CPU core slowing down the application) as apparently something was broadcasting Windows Messages like crazy.
Investigating and Solving the message flood is on the back-log with a reasonably high priority, but the highest priority issue was fixing the high CPU usage in the first place.
Apparently more users suffer from this, as there is a Vcl.Forms.TApplication.ActionUpdateDelay property which TApplication.Idle uses to call the Windows API function SetTimer to rate-limit the TApplication.DoActionIdle call tree. Luckily SetTimer does have documentation on the unit of ActionUpdateDelay: it’s milliseconds.
I’ve set it to 10 as that updating the actions ~100 times a second is fast enough for this application.
–jeroen
via:
- Mouse move messages: windows – Why are : visible, control assigned TActions affecting the CPU usage of the application? – Stack Overflow
- Using a single CPU core: delphi – TActionlist, OnUpdate, High CPU Usage? – Stack Overflow
- Idle high CPU usage: Q335808 – Messages using a lot of CPU when app is idle | DevExpress Support Center
Filed under: Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Delphi 2007, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development
