Delay not working

hi!

i have this desktop pressed event:

Sub Pressed() Handles Pressed
  For i As Integer = 1 To 3
    Me.Caption = Str(i)
    delay(1,"s")
  Next
End Sub

and this is the method:

Public Sub delay(delay as integer, type as string)
  Dim delayInMilliseconds As Double
  
  Select Case type
  Case "ms" // Milissegundos
    delayInMilliseconds = delay
  Case "s" // Segundos
    delayInMilliseconds = delay * 1000
  Case "m" // Minutos
    delayInMilliseconds = delay * 60 * 1000
  Case "h" // Horas
    delayInMilliseconds = delay * 60 * 60 * 1000
  Else
    Raise New InvalidArgumentException("Tipo inválido. Use 'ms', 's', 'm' ou 'h'.")
  End Select
  
  Dim endTime As Double = System.Ticks + delayInMilliseconds
  
  While System.Ticks < endTime
    App.DoEvents(1)
  Wend  
  
End Sub

why it’s not working?

You are not supposed to call DoEvents from a desktop app; it is for console apps only. You could use a timer instead.

3 Likes

Or use a thread, then pause/sleep the thread for your delay in milliseconds.

xojo could have this natively!

If you have MBS there is SleepMBS. But keep in mind that it also locks up your app just as your Delay method will.

Looking at your code, I’m wondering what the purpose of the delay is. Is it to create a cooldown for your Pressed event?

i don’t want to use external plugins, etc

i need the delay to paint an animated gif on a canvas.

… i splitted the gif frames and put it on a dictionary.
now i want to show it frame by frame, with a 16ms delay.

That’s exactly what a timer is for. Create a timer with ModeMultiple and period 16ms and call Canvas invalidate from it. Then have a counter you increase by one each time tracking frames and draw that image in canvas draw event. If you try to delay and do this synchronously it won’t work - canvas invalidate only lets you draw one frame per call

5 Likes

Nope you can’t xojo is not a simple synchonous app, you need to be asyc to keep events going.
Build a console app, with that you can do this. Just don’t do this in desktop or other apps.

You’ve got some good advice: timer is the right way to go. I have free Xojo module that handles animations like this. The ZAZ: Animation Kit

DoEvents, no matter the situation, is always the wrong tool for job in a desktop app. The only reason it was ever even available to desktop apps is because the IDE needed (or maybe still needs) it for the splash screen. And that was also an abuse of the function.

DoEvents allows your code to loop in on itself, more formally known as reentrant code. This is because your app is already running DoEvents behind the scenes. Every event that fires on the main thread - which is nearly all of them - starts from that DoEvents function. So your code could start handling a timer run event inside your button push event. And If you do any exception logging, you’ll find yourself with some very puzzling exception reports.

Use the timer and update the canvas accordingly.

3 Likes

ok. let me organize my ideas here…

the timer will refresh the canvas, after some time.
the canvas, only paint the stuff, and inside the paint event, i need to put a method that will paint something… ok.

but, sometimes i’ll need to paint something “faster/slower” so i’ll need the timer to be faster, or to be slower… so in each case i’ll change the timer as needed. right? ok!…

but and when i need a delay on an opening process, for example…
i launch dropbox.app, then i launch onedrive.app. i want to open with a delay of 15minutes…

the same way?

on timer.run event “launch app1”, put a counter then “launch app2”?

i tried your example and noticed that “desktopButton” does not work, only “pushButton”
(window, not desktopWindow, etc)
is there a reason for that?

Maybe because of this:

The ZAZ: Animation Kit

Current Version
Last updated June 13th, 2015.

1 Like

Oh… I’m using it in an API 2 app now. I didn’t realize I never released it. There’s an updated version in my Beacon app, but I’ll need to make a formal update.

1 Like

Alternatively, if it’s not too boring you could just use a built in “Progress Wheel” control. Typically it shows a spinning circle (at least on a Mac). You can enable or disable the spinning, hide it etc. It will spin all on its own, so long as you don’t tie up the main thread by running code.