How to interrupt your code


I received a question:


 


 


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


 


Use Visual Studio Test framework to create tests for your code


Sample program to create multiple threads


Create multiple threads from within your application


More Multithread capabilities: interthread synchronization, error checking


Webcrawl a blog to retrieve all entries locally: RSS on steroids


The VB version of the Blog Crawler


 


 


 


CLEAR ALL


CLEAR


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


?”Escape=”,SET(“Escape”)


ON ESCAPE do OnEscapeHandler


FOR i = 1 TO 12


      APPEND FROM DBF(“foo”)  && Double the size each iteration


ENDFOR


?”Reccount=”,RECCOUNT()


?”query starting: try to stop it!”


ns=SECONDS()


TRY


      * 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


      ?”Caught”,ex.Message,ex.Details,ex.UserValue


ENDTRY


 


?”Query done”


?SECONDS()-ns


 


RETURN


PROCEDURE OnEscapeHandler


      ?”Interrupted”


      THROW “interrupted from “+PROGRAM()


      RETURN


 


FUNCTION WasKeyPressed as Boolean


      IF INKEY()>0


            THROW “Key pressed from “+PROGRAM()


      ENDIF


      RETURN .T.


 


 

Comments (6)

  1. Steven Black says:

    Hey Calvin!

    The program never interrupts here, regardless of what flavour of it I run.

    What are some other influences that may affect this?

    Using Visual FoxPro 09.00.0000.3504 for Windows.

  2. SednaY says:

    Calvin is probably implying that you need to run the main code in a thread (see the URLs that he lists). For example, his vfp web crawler has the ability to interrupt the web crawling..

  3. Hi Calvin

    I had done a virtually identical thing with many versions of Visual FoxPro including SP2 and version 9. Works for me.

    With a local or remote view, if you had results in the cursor and you interrupt a REQUERY that way, the previous results remain.

    You have to handle error 1839 to do that.

    If you’re not using a view, but simply re-executing an SQL, you can use a variations of Andy Kramek’s SafeSelect technique. Put a conditional check in that if the user interrupted, do not zap the original cursor and do not fill the original cursor with new contents.

    Mike Yearwood

  4. Bernard Bout says:

    The OnEscape takes a while to kick in.

    However the "WasKeyPressed" gives an almost instant response.

    Nice to see you blogging about VFP again!

  5. Serial number blank cd says:

    hello

    i happy for find your site and i hope you help me

    sorry i cannot good speak english anyway i have a question .do have blank cd many information or serial number , factory name, mode and what is make this cd info in vb6 source/code ?

    please help me

    i wait you

    thank you very much

    reza

  6. Mike Potjer says:

    In response to Steve’s question, you must also have _VFP.AutoYield = .T. in order for the escape routine to work.

    Thanks Calvin!  This article helped me to create some "handler" code which makes it easy to turn this capability on and off whenever I need it.