waitfortask
waitfortask
TASKID

The waitfortask statement temporarily pauses a procedure until the specified task is complete.

Parameters

This statement has one parameter:

taskid – the ID of the task to wait for (either a timer or a urltask().

Description

This statement temporarily pauses a procedure until the specified task is complete. The code for the task must contain a resumeaftertask statement with the same ID as the final statement in the task.

This statement is most commonly used with the urltask( function. In its simplest form, the statement and function can be paired directly together. In this example, a large file is downloaded from a web site, and then uncompressed.

    waitfortask urltask("http://www.somesite.com/somebigfile.zip",
        "file","~/Documents/Test/SomeBigFile.zip",
        "code",{resumeaftertask «taskid»})
    uncompress "~/Documents/Test/SomeBigFile.zip"
    nsnotify "Download Finished and Uncompressed"

Because this code uses the urltask( function, Panorama does not “hang” while the file is downloaded. Even if it takes several minutes to download, Panorama will be fully responsive the whole time. You can click on other windows, do whatever you want. When the download finishes, the code will resume with the first statement after the waitfortask function, in this case the uncompress statement.

Note that since the user can do anything while the task is running, your code cannot assume that Panorama is in the same state when the task resumes. There may be a different window open, or the database that triggered the procedure might not even be open at all any more. If the code relies on a particular window or database being active, it must test for that, and if necessary make necessary adjustments, for example with the window statement.

In the example above, the code associated with the task doesn’t do anything except resume the additional code. But the code can do more, as long as the final statement is the resumeaftertask statement. Here is a more complicated example that uses the openasyncprogresswindow statement to open a window to display the progress of the download as it proceeds.

    let url = "http://www.somesite.com/somebigfile.zip",
    openasyncprogresswindow initializedictionary(
        "CAPTION",replace(url,"http://","")
    )
    let finishWindowCode = getdictionaryvalue(asyncTaskInfo,"FINISHCODE")
    let progressVariable = getdictionaryvalue(asyncTaskInfo,"PROGRESSVARIABLE")

    waitfortask urltask(url,
        "file","~/Documents/Test/SomeBigFile.zip",
        "progress",progressVariable,
        "code",finishWindowCode+{ resumeaftertask «taskid»})
    uncompress "~/Documents/Test/SomeBigFile.zip"
    nsnotify "Download Finished and Uncompressed"

You don’t have to pair the waitfortask statement and urltask( on the same line, you can separate them but keep them connected with a variable like this.

    let taskid = urltask(...)
    ...
    ... extra code before pausing
    ...
    waitfortask taskid
    ...
    ... resume after url is downloaded
    ...

Normally there is no connection between the main procedure and the code that is running asynchronously, each have their own, separate local variables. However, the asynchronous code can use the setwaitinglocal statement to pass data back to the original procedure. See the setwaitinglocal help page to learn more.

### Using WaitForTask with a Timer

It’s also possible to use the waitfortask statement with a timer. This code pauses for 30 seconds, then resumes. During the pause, Panorama is fully functional, you can click on other windows, perform whatever operations you want.

    let delay = 30
    let taskid = info("guid")
    starttimer taskid,
        "code",{resumeaftertask }+quoted(taskid),
        "repeat",1,
        "next",supernow()+delay
    waitfortask taskid
    ...
    ... resume after 30 second delay
    ...

Does the code above seem overly complicated for a simple delay? Yeah, we thought so too. So you can skip all that and just use the wait statement.

    wait 30

If you’re the sort that likes to peek under the hood, you can view the source of the wait statement and see that it is actually written using the waitfortask and resumeaftertask statements.

See Also

- Automatic Field Code -- running a short program when data is entered into a field.
- call -- allows a procedure to call a separate procedure within the current database as a subroutine.
- call( -- allows a procedure to be called as a subroutine within a formula and return a result.
- calledby( -- returns true if this function is in code called by the specified database, the specified procedure, or both.
- callerslocalvariablevalue( -- allows a subroutine to access a local variable in the procedure that called it.
- callingdatabase( -- returns the name of the database that called this procedure as a subroutine, if any.
- callingprocedure( -- returns the name of the procedure that called this procedure as a subroutine, if any.
- callwithin -- allows a procedure to call a mini-procedure within a separate procedure within the current database as a subroutine.
- callwithin( -- allows a "mini-procedure" to be called as a subroutine within a formula and return a result.
- callwithindatabase( -- returns true if the current procedure was called by another procedure in the same database, false if it was called by a procedure in another database.
- case -- allows multiple decisions to be chained together (also see the elseif statement).
- catch -- works with try and endcatch to trap errors in a sequence of statements.
- changetimer -- modifies a repeating task that will be performed periodically when Panorama is not otherwise busy.
- Custom Database Initialization -- using an .Initialize procedure to automatically run custom code when a database opens.
- debug -- stops the current program, allowing you to examine variables or single step.
- defaultcase -- works together with the case statement to specify statements that will be executed if none of the *case* statements are true.
- disableabort -- prevents loops from being stopped early by pressing SHIFT-COMMAND-ESCAPE or by exceeding the maximum allowed loop time.
- else -- works together with the if statement to specify statements that will be executed for both the *true* and *false* cases.
- elseif -- allows multiple if decisions to be chained together.
- enableabort -- allows the SHIFT-COMMAND-ESCAPE key sequence to stop an endless loop.
- endcase -- marks the end of statements controlled by a previoius case statement.
- endcatch -- works with try and catch to trap errors in a sequence of statements.
- endif -- marks the end of statements controlled by a previoius if statement.
- endloop -- is used at the end of a loop.
- endnoshow -- resumes the output of text and graphics after it has been disabled with the noshow statement.
- Error Handling -- Techniques for trapping runtime errors instead of letting them abort the program.
- Error Wizard -- Advanced dialog for displaying program errors.
- execute -- allows a procedure to call a sequence of statements within the current procedure as a "mini-subroutine".
- execute( -- allows a formula to execute a sequence of statements and return a result.
- executeasap -- executes the specified code at the first possible opportunity, non-atomically.
- executecatcherrors -- is the same as the execute statement, except for the fact that if an error occurs while running, it can be trapped by an if error statement immediately following the executecatcherrors statement.
- executelocal -- is the same as the execute statement, but it shares local variables with the procedure that called it.
- farcall -- allows a procedure to call a separate procedure within a different database as a subroutine.
- farcallwithin -- allows a procedure to call a mini-procedure within a separate procedure in a different database as a subroutine.
- for -- is used at the beginning of a loop that loops a fixed number of times.
- goto -- allows a procedure to arbitrarily jump from one spot to another within the procedure.
- if -- decides what code to execute next.
- Implicitly Triggered Procedures -- Procedures that are triggered automatically when the user performs some normal Panorama action are said to be "implicitly triggered."
- info("callerslocalvariables") -- returns a list of local variables defined in the procedure that called the current procedure.
- info("computername") -- returns the name of the computer (as set up in the System Preferences Sharing panel).
- info("error") -- returns the most recent error message.
- info("labels") -- lists the labels in the current procedure.
- info("noshow") -- returns true if noshow is currently turned on, false if it is not.
- info("procedurestack") -- returns the contents of Panorama's procedure call stack.
- info("runningatomic") -- returns true if the current procedure is running as a "atomic" procedure.
- loop -- is used at the beginning of a loop.
- looparray -- is used at the beginning of a loop that loops over the elements of an array.
- loopdataarray -- is used at the beginning of a loop that loops over the elements of a data array.
- loopindex -- allows a procedure to determine how many times a loop has been repeated.
- loopwhile -- is used at the beginning of a loop.
- noimplicitassignment -- does nothing, and is only retained for compatibility with earlier versions.
- nop -- does nothing (**n**o **op**eration).
- noshow -- temporarily disables the output of text and graphics.
- onerror -- can be used to catch all errors that are not trapped by if error or try statements.
- onfailedresume -- is used to setup a semi-graceful recovery if a resume statement fails because there was no pause statement.
- parameter( -- is used to transfer data between a main procedure and a subroutine.
- pause -- temporarily pauses a procedure.
- Preventing Endless Loops -- setting up a timeout limit to prevent endless loops.
- quit -- quits Panorama.
- repeatloopif -- decides whether to continue with a loop or to start over again from the top.
- resume -- resumes a procedure that has been temporarily halted with the pause statement.
- resumeaftertask -- resumes after a waitfortask statement.
- return -- ends a subroutine.
- returnerror -- passes an error back to the current subroutines calling procedure.
- setcallerslocal -- allows a subroutine to modify a local variable in the procedure that called it.
- seterror -- changes the error message returned by info("error").
- setparameter -- is used to transfer data from a subroutine back to the main procedure that called it.
- setwaitinglocal -- assigns a value to a local variable in the parent procedure of an asynchronous task, allowing the asynchronouse code to pass a value back to the code that spawned it.
- shortcall -- allows a procedure to call a sequence of statements within the current procedure as a "mini-subroutine".
- starttimer -- sets up and starts a repeating task that will be performed periodically when Panorama is not otherwise busy.
- stop -- stops all running procedures immediately.
- stoploopif -- decides whether to continue with a loop or to exit the loop immediately.
- throwerror -- causes an immediate error.
- Timer Workshop -- provides a tool for monitoring timers and testing timer configurations.
- timerexists( -- checks to see whether a timer exists.
- Timers -- executing recurring periodic background code at fixed intervals.
- try -- works with catch and endcatch to trap errors in a sequence of statements.
- Understanding the Run Loop -- explanation of how Panorama code interacts with the run loop to respond to mouse clicks, keyboard presses, display updates and other events that require attention.
- until -- is used at the end of a loop, and can control how many times the loop is executed.
- usecallerslocalvariables -- temporarily swaps out a subroutine's current local variables with the local variables of the procedure that called this subroutine. The statement can be used only in a subroutine, not in a calling procedure.
- usefunctioncallerslocalvariables -- temporarily swaps out a procedures current local variables with the local variables of the procedure that called this the call(, callwithin( or execute( function.
- usemylocalvariables -- reverses the action of the UseCallersLocalVariables statement, switching back to the current procedure's normal local variables.
- wait -- pauses the program for a specified period of time.
- while -- is used at the end of a loop, and can control how many times the loop is executed.

History

Version | Status | Notes
10.2 | New | New in this version.