Delphi idle handler only fires when I move the mouse

无人久伴 提交于 2019-12-05 20:02:49

As mentioned in the comments, Sleep in the idle handler will do no good, also the bacground processing will stall if there is no activity on the application.

You can however lower the CPU usage w/o much disturbing effects:
After processing all OnIdle events, the application will call WaitMessage (which will sleep while the message queue is empty), if the Done parameter is True - you can just unconditionally set it in your handler.

As for background processing, use either a thread and call back to the main thread via Synchronize or, if you really-really have to, use a timer and don't ever forget to handle reentrancy (both solutions will by the way wake the application even while WaitMessage).

Use the source, Luke. :)

Look at the Forms unit, specifically TApplication.Idle. It contains, in part, the following:

Done := True;
try
  if Assigned(FOnIdle) then FOnIdle(Self, Done);
  if Done then
    if FActionUpdateDelay <= 0 then
      DoActionIdle
  // Excluded to avoid copyright violation
  // See also the else portion, which contains (in part)
  else
    if IdleTimerHandle = 0 then
    begin
      IdleTimerHandle := SetTimer(0, 0, FActionUpdateDelay, IdleTimerDelegate);
      if IdleTimerHandle = 0 then
        DoActionIdle
    end;
finally
  // Omitted
end;

As you can see, DoActionIdle is only called when either Done = True and FActionUpdateDelay <= 0 or IdleTimerHandle = 0. DoActionIdle (also part of TApplication) is what calls UpdateAction. So if neither of the above conditions are met, TAction.OnUpdate is never called.

There's a separate method, TApplication.DoMouseIdle, that you may want to peruse as well.

Get rid of that OnIdle event handler, you accepted it is there just in case.

If you later need to perform background tasks, learn how to use threads. To get a specific frequency, you're allowed to use sleep or any other technique within a thread.

My advice is in this way because, as you see, that way of do things is interfering with other parts of your application. If it is a bug in the TApplication, I don't know, maybe it is. If you want to investigate more, make a copy of your project, check everything and if you think this have to work another way, fill a QC entry about that.

I was looking the XE source code and it seems Ok, they set an event to update the actions if the Idle event is not done.. I don't see a bug there. I have no pre-2010 ready installations to check ancient versions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!