Xojo.Core.Timer.CallLater Question

I’m expecting that someone from Xojo will need to answer this question as it has to do with how the timer in the new framework gets queued, etc.

So I have a method that creates a number of window objects in the back ground. Most users will have 1 or at most maybe 2 or 3 of these, but I have one user who has over 20 that get opened (these windows are for controlling specific physical objects).

Anyhow, here’s some pseudo code that I’m using:

  r = MSDB.SQLSelect("Select TheIndex FROM MyTable ORDER BY TheIndex ASC")
  If r <> Nil and Not r.EOF Then    
    Do
      If r.Field("TheIndex") <> Nil and r.Field("TheIndex").Value <> Nil Then
        Dim mIndex as Integer = r.Field("TheIndex").IntegerValue
        Xojo.Core.Timer.CallLater(0,AddressOf CreateWindowViaTimer, mIndex)
      End If
      r.MoveNext
    Loop Until r.EOF
  End If

So the method CreateWindowViaTimer is the method that creates the window. I figured it would be better to have timers fire to create these (I can’t do it in thread since a window is a UI object) and not hold up the UI.

So here’s that method:

Sub CreateWindowViaTimer(mlIndx as Auto)
  Dim mIndex as Integer = mIndx
  Dim w as New MyWindowControl(AGlobalArray,mIndex)  ' Create the window
  mWallWindows.Append w   ' add to the array
End Sub

So in OS X, the timers seem to fire in a FIFO pattern. So the end result is that window with a value of mIndex = 0 gets added to the mWallWindows array first, the second gets added on second, et.

In Windows, it appears the timers fire in a LIFO pattern. This screws up my array and the window with the largest index gets added to the array first.

Can I rely on the order of the Timer’s firing when using CallLater like this? If Windows is always going to be LIFO and Mac FIFO, I can make adjustments. I have and I’ve tested it and it seems to work fine. However, I need to know if I can rely on that.

If I am spinning up 20 timers with CallLater, what exactly is the firing order going to be? Can I rely on that?

I would not.

Suggestion. Rather than starting the Timer within the loop, build an array there and send it to your Timer all at once. Within the Timer, process the first element of the array and, if there are more, start the Timer again with the remaining elements. You’ll get the effect you desire (I think) and the order is guaranteed.

Great idea, Kem.

So now I take and read the indexes from the database and populate an array with them. Then I pass that array into the timer as the parameter. Then in the timer method, I pull off the 0th element of the array and create the window. Then if there are elements still in the array, I call the timer again and pass in the array with the remaining elements. Works great and yeah, guarantees my order…

[quote=187343:@Jon Ogden]So in OS X, the timers seem to fire in a FIFO pattern. So the end result is that window with a value of mIndex = 0 gets added to the mWallWindows array first, the second gets added on second, et.

In Windows, it appears the timers fire in a LIFO pattern. This screws up my array and the window with the largest index gets added to the array first.

Can I rely on the order of the Timer’s firing when using CallLater like this? If Windows is always going to be LIFO and Mac FIFO, I can make adjustments. I have and I’ve tested it and it seems to work fine. However, I need to know if I can rely on that.[/quote]

You maybe able to insure to ensure a reliable firing order by enabling timers in the others action event.