User Interrupt to Running Script

Started by fhammer, May 04, 2020, 01:22:29 PM

Previous topic - Next topic

fhammer

I have a script which is (intentionally) waiting for an asynchronous event (e.g. incoming call).
I'm looking for a way to allow the user to interrupt the script,
so that I can take action (e.g. terminate gracefully or interact with the user).

I'm using an Extender function [e.g. FcnX(event,timeout)] which returns @TRUE or @FALSE depending on whether the event occurs within a specified time. In my case I want to effectively wait-forever.

I want to be able to interact with the user, with a low probability of missing the event.
It's OK if I miss events during the user interaction.

I've looked at putting the call to FcnX in a loop with a short timeout, and checking for user interrupts at each interval:

timeout = 10                             ; 10 milliseconds
While @TRUE
  If FcnX(event,timeout)              ; wait 10 ms for event
  Else                                         ; event did not occur
    If WaitForKeyEx("^!{END}",1) ; wait 1 sec for Crt-Alt-End
      (process user interrupt)
    Endif
EndWhile

One problem with the above, is that 99% of the time is spent checking for Ctrl-Alt-End, due to the fact that the timeout parameter WaitForKeyEx does not support small-fractional seconds. This means that the probability of missing an event would be very high. However, if I increase theFcnX event timout, I will miss a lot of attempted user interrupts.

I also looked at using IsKeyDown(), but that only works with the Ctrl and Shift keys, and I want the user to be able do other stuff while the script is running. The best idea I could come up with is a combination of IsKeyDown and MouseButtonInfo to check for Ctrl-Shift-(Right-Button-Down). This should execute very quickly (in place of WaitForKeyEx) and not likely interfere with other user processes.

I looked at the extenders, help forum and couldn't find anything. I also checked the Error Handling documentation for a way to trap an externally initiated script termination.

I suspect the desire for a user to interrupt a script, has come up before, and am looking for advice or references.

Any help would be appreciated.

td

Your assertion is that WaitForKeyEx is limited to a minimum of 1 second is not correct.  WaitForKeyEx accepts a floating point number as its second parameter so you can specify partial seconds as the wait time.

Another common approach is to use the IsKeyDown function in a loop structure.  It does require instructing the user to hold a particular key until your script terminates. You can find a couple examples of this approach in the default.wbt file in your WinBatch "system" folder. Search for "IsKeyDown" in the file to find the examples.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

fhammer

Thanks td,

I ended up using an outer IsKeyDown(@CTRL & @SHIFT) loop with an inner WaitforKeyEx("^+{END}",.1) breakout. I found that IskeyDown has very litle overhead (over 100 times faster that than WaitforKey, which takes at least .1 second, no matter how low the specified timeout).

I'm glad you are still with Winbatch.

td

Actually, it is fairly easy to demonstrate that WaitForKeyEx has a minimum wait time of about 0.02 and 0.03 seconds in most cases. That limit has to do with the granularity of the Windows tick counter used but is also influenced to a lesser degree by system capacity and load.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade