Age Old Question of "Pausing" Code (Michel B?)

  1. 3 months ago

    Ok, call me dense, but even after going through the Forum (as well as guides and tutorials) and reading every reference I could find about "pausing" code I just can't seem to grasp the concept of moving from the old procedural way of "pausing" a process to an event-based way of doing it. Don't get me wrong, I'm well aware of the differences between procedural and event-based programming. However, this seemingly simple problem/task has me struggling for some reason.

    Here's the basic thing I need to do in my app and on multiple occasions:

    1. Trigger an event.
    2. Run some code.
    3. Update the UI with a graphic and text.
    4. Pause for 2 seconds.
    5. Update the UI with another graphic and text.
    6. Pause for 2 seconds.
    7. Update the UI with the final graphic and text.
    8. Pause for 2 seconds.
    9. Run some more code.
    10. Complete the event.

    What am I missing? I've played around with timers, ticks, Xojo.Core.Timer.CallLater, etc., but I just can't seem to achieve the desired result.

    Any help would be appreciated. (Michel B, are you listening?) Thanks in advance. :-)

    A Timer and a Thread are another option. Put your code into a Thread's Run event. At certain intervals, update a property (or properties) with what you want to show in the UI and then sleep the thread for 2 seconds. A separate Timer grabs the property values and displays them in the UI.

    Here's a quick sample project: http://cdn.xojo.com/BlogExamples/PauseCode.xojo_binary_project

  2. Russ L

    Feb 11 Pre-Release Testers, Xojo Pro

    you could subclass a timer with a property of delay

    when you start the timer, you set the delay you want and the current time (computed property)
    in the timer action check the current time to see if your delay has expired yet and if it has
    perform the action or raise an event

    a version of this was used as a sort of stopwatch in some code i saw a long time ago.
    to delay sending commands to a serial device
    nicely re-usable and doesn't mean you have loads of timers

  3. Kevin G

    Feb 11 Pre-Release Testers, Xojo Pro Gatesheed, England

    Not sure what you have tried but here is a print out of a very basic example using a window with a timer control, a label, a push button and a property.

    Window1
    Class Window1
    Inherits Window
    Private mTimerState_ As Int32
    
    Window1 Control RunPushButton:
    Sub Action() 
    Self.mTimerState_ = 0
       Timer1.Mode = Timer.ModeMultiple
    Timer1.Enabled = True 
    End Sub
    
    Window1 Control Timer1:
    Sub Action()
    Dim caption As String
    Self.mTimerState_ = Self.mTimerState_ + 1
    Select Case Self.mTimerState_ 
    Case 1
    caption = "1st Action" 
    Case 2
    caption = "2nd Action" 
    Case 3
    caption = "3rd Action" 
    Case 4
          caption = "Last Action"
    Me.Enabled = False 
    End Select
    
    Self.Label1.Text = caption 
    End Sub
    End Class
  4. Russ, Kevin, Thank you both for your quick replies.

    Russ, that's funny because that's the next thing I was going to try.

    Kevin, I did in fact come across that (or very similar) code and couldn't determine if it would work or not for my particular issue.

    I'll try both of your suggestions and report back the first chance I get. Both will require me to rework some my code so it may be a while.

    Thanks again. :-)

  5. Paul L

    Feb 11 Xojo Inc Answer http://docs.xojo.com

    A Timer and a Thread are another option. Put your code into a Thread's Run event. At certain intervals, update a property (or properties) with what you want to show in the UI and then sleep the thread for 2 seconds. A separate Timer grabs the property values and displays them in the UI.

    Here's a quick sample project: http://cdn.xojo.com/BlogExamples/PauseCode.xojo_binary_project

  6. Joost R

    Feb 11 Pre-Release Testers, Xojo Pro The Netherlands

    Be aware of this:

    Threads run in the background, but are temporarily blocked by certain user actions:
    
    While the mouse button is held down,
    While a window is being dragged,
    While a menu in the menu bar is pulled down,
    While the mouse button is pressed on a control in a window (not true of Windows)
  7. Joost R

    Feb 11 Pre-Release Testers, Xojo Pro The Netherlands

    If you need to do background processing which must continue, I'd prefer putting this code in a helper application.

  8. Paul, That's another great recommendation (and thanks for the sample code). I haven't attempted to combine the two in the way you suggest. I'll add it to my list of things to try.

    Joost, Thanks for the heads-up. I'll keep that in mind when deciding on the right solution.

    :-)

  9. Michel B

    Feb 11 Pre-Release Testers RubberViews.com

    Steven,

    The best way I have found to go from procedural to event base is to use a timer any time I need to pause, at least when loops are not involved.

    Here is your example :

    1. Trigger an event.
    2. Run some code.
    3. Update the UI with a graphic and text. // Best is to have a method
    4. Start a 2 seconds multiple timer AND RETURN FROM THE EVENT

    -- > this goes in the Action event of the timer : Update the UI with another graphic and text.

    1. Pause for 2 seconds. // Taken care of by the timer
    2. Pause for 2 seconds. // Taken care of by the timer

    To count the number of times the timer triggered a refresh of the display, use a static variable which you increment each time the timer fires. When comes time to stop, something like this will do nicely :

    me.mode = Timer.ModeOff

    9. Run some more code. -- > That part is in the Action event of the timer, executes when the number of times it has executed in the static variable is OK.

    http://docs.xojo.com/Static

  10. Success!!! I just wanted to report back and let everyone know that I achieved the desired result. I took what I learned from your comments (and examples) and came up with a solution that uses a timer, thread, method, and global property as an array. It seems a little clunky so I'm sure I'll go back and simplify/refine the solution over time. But, for now, it works!

    [Joost, I don't have to worry about the UI interfering with the thread at the moment. Though, if at some point I do, I'll keep your warnings in mind.]

    Thank you all again for your assistance. I'm happy to find that Xojo has such a supportive developer's community. :-)

or Sign Up to reply!