Simply, is there a way of interrupting a vfp sql query once it has started short of closing down the process ?
I am running some complex queries on very large datasets which can sometimes take many minutes to complete.
Typically, a program that runs on your computer has a main thread of execution.
On this thread, the processor is fetching instructions from memory and executing them. If this thread is busy, perhaps executing a query, or even just in a loop, the processor won’t check for user input.
Imagine the processor to be a person working in a factory. If she’s busy, then she doesn’t have time to look at her email. One way to fix this is to add an item to her workload to look at the email once in a while. If she’s in a loop (repetitive work), then adding an item in the loop would work.
Another way to fix this is to have another person (thread) in the factory. His job is to watch the email for any pending requests. He has the ability to interrupt her work.
Many applications are single threaded. That means there is only one person responsible for doing the work, listening for input, and updating the User Interface. Sometimes he’s very busy, so to the user, the application seems non-responsive.
As above, a solution is to create another thread (think of it as adding another person who can help do the work). This other thread can monitor the email.
The sample below creates a temporary table of many records. It then does a non-optimized Cartesian join of the table with itself, making the main thread busy.
The Set Escape command tells the main thread to check for the Escape key (looking for the boss at the door).
The On Escape command says what to do if the boss is there.
As an alternative, you can inject your own code into the work loop. The WasKeyPressed function, for example, checks for a keypress.
If work is interrupted, the worker may not have finished the current task, perhaps leaving the environment in an abnormal state.
See also other threading samples, which allow you to create multiple threads in VB and FoxPro
MODIFY COMMAND PROGRAM() NOWAIT
CREATE CURSOR foo (name c(10))
INSERT INTO foo (name ) VALUES ("foo")
*Try with ESCAPE ON and OFF
SET ESCAPE ON
ON ESCAPE do OnEscapeHandler
FOR i = 1 TO 12
APPEND FROM DBF("foo") && Double the size each iteration
?"query starting: try to stop it!"
* Cartesian product unoptimized join
SELECT * FROM foo, foo bar WHERE foo.name=bar.name INTO CURSOR results
* Sample that calls a method that checks for key press
* SELECT * FROM foo, foo bar WHERE foo.name=bar.name AND WasKeyPressed() INTO CURSOR results
CATCH TO ex
THROW "interrupted from "+PROGRAM()
FUNCTION WasKeyPressed as Boolean
THROW "Key pressed from "+PROGRAM()