Unknown Timers Causing Delays

In trying to track down the cause of a long beachball following the run of a procedure triggered by a timer. I’ve discoverfed via the Timer Workshop that a huge number of Temp timers are being created, all set to run at the same instant.

Trying to see if something I had done was at fault, searches for wait or delay have turned up nothing.

The scroll bar on the screen shot shows that there are quite a few of them. Eventually they all disappear as does the beachball. I never get the opportunity to look into one to see what it’s doing

The quantity and the length of the delay are seemingly effected by the size of the array processed in a LoopArray, but all tasks within it have been executed and done.

What are they and how can I eliminate them?

Screenshot 2024-09-27 at 7.18.50 AM

Panorama internally uses lots of anonymous timers, you aren’t finding them because they are generated in the Objective C code. There are dozens of places where these are used, there’s no way to tell what the timer does from the Timer workshop. Normally however they wouldn’t stack up like this - your loop must not have any breaks where the timer code can run.

Is this a shared database? Anonymous timers are heavily used by the sharing code, for example for record locking/unlocking, so that’s a good possibility. But there are also many other times where these are used.

These aren’t actually set to run at a particular instant, they are set to run as soon as possible. Since they were all triggered within a second, they show up at the same time. Keep in mind that the “Next Runtime” is the earliest time that the timer can run, but it’s not guaranteed. If there is other code already running then the timer will wait in line for it’s turn, which could be milliseconds or tens of seconds.

I think they are locked so that you can’t see what they are doing.

Hopefully you’ve already figured out from what I’ve said that these can’t be eliminated.

Nope. But I am using secret windows up to the point in the LoopArray where it’s necessary to open a form in order to use PrintToPDF.

In this case it’s several minutes which is why I’m trying to get around it.

And I have clearly tied it to the size of the array in the LoopArray.

Well if you want to reveal what the code in the LoopArray does, perhaps I can tell you why timers are involved.

Timers are also used for some implicit triggers, for example if you have code that runs when opening a form or bringing it to the front.

Select

By paring down the procedure in the loop, I got it down to nothing but a Select. Every time my LoopArray does a select, a timer is added, such as _Temp_676221384.

By the time a sizeable LoopArray has been processed the backlog of these timers leaves a beachball on screen for some time. As much as five minutes for an array of 50 elements. Often enough it also eliminates my timer when they’re all cleared out.

zlog "start "+info("timers")
   LoopArray MyArray,cr(),This 
        Select That = This 
   EndLoop
zlog "End "+info("timers")

[Monitor/Procedure_B] start
[Monitor/Procedure_B] End InstrumentationLog_fs_monitor_0
[Monitor/Procedure_B] _Temp_677040657
[Monitor/Procedure_B] _Temp_677040686
[Monitor/Procedure_B] _Temp_677040715
[Monitor/Procedure_B] _Temp_677040744
[Monitor/Procedure_B] _Temp_677040773
[Monitor/Procedure_B] _Temp_677040801
[Monitor/Procedure_B] _Temp_677040830
[Monitor/Procedure_B] _Temp_677040859
[Monitor/Procedure_B] _Temp_677040888

Sorry it’s taken so long to follow up on this – it’s been a busy week.

I created a procedure to test this:

let parts = listchoices(«Part Name»,cr())
zlog labelize(parts)
looparray parts,cr(),part
    select «Part Name»=part
endloop
zlog info("timers")

When I run the code, no timers are created:

[TIME: 7:43 PM]
[Kurt Arnlund Experiments/Select Loop] === parts ============
[Kurt Arnlund Experiments/Select Loop] Medium Widget
[Kurt Arnlund Experiments/Select Loop] Big Widget
[Kurt Arnlund Experiments/Select Loop] Tiny Widget
[Kurt Arnlund Experiments/Select Loop] Small Widget
[Kurt Arnlund Experiments/Select Loop] Widget
[Kurt Arnlund Experiments/Select Loop] === END OF parts ============
[Kurt Arnlund Experiments/Select Loop]

Panorama does use temporary timers internally, they are always named _Temp_nnnnnn. There are dozens of places where timers are used. But looking thru the list, one place jumps out at me. Does your database contain a .CurrentRecord procedure? I’ll bet it does - if so, Panorama will create a timer every time you change the current record (which your select statement will do).

Ok, I added a .CurrentRecord to my database, and voila! Timers were created. So I’m sure that is what you are seeing.

If you use noshow, no timers are created. Other than that the only solution would be to remove the .CurrentRecord procedure. If you look back at my previous posts on this, you’ll see that I always strongly discourage use of .CurrentRecord. This sort of problem is why.

You nailed it. Thanks.

The file had a .CurrentRecord procedure that refreshed a single variable. No more, no less. Eliminating it made the temp timers disappear.