Sign in to follow this  
Followers 0
mjolnirmarkiv

Yet another 'how to interrupt the function' question

12 posts in this topic

#1 ·  Posted (edited)

Hi,

I know this is ratherr tired topic, and yes, I've read the tutorial, but either I'm missing smth, or it doesn't answer my needs entirely.

Here's an outline of actual code, in which I need to interrupt My Func () and return to main loop. For now, as you may see, it exits the script:

#include <GUIConstantsEx.au3>

Global $gui = GUICreate ("Stopped", 200, 70)
Global $run_button = GUICtrlCreateButton ("Run", 20, 20, 70, 30)
Global $exit_button = GUICtrlCreateButton ("Exit", 110, 20, 70, 30)

GUISetState (@SW_SHOW)

Global $gui_message

While $gui_message <> $exit_button
  $gui_message =  GUIGetMsg ()

  Switch $gui_message

    Case $run_button
      WinSetTitle ($gui, "", "Running...")
      GUICtrlSetState ($run_button, $GUI_DISABLE)
      GUICtrlSetState ($exit_button, $GUI_DISABLE)

      MyFunc ()

      GUICtrlSetState ($run_button, $GUI_ENABLE)
      GUICtrlSetState ($exit_button, $GUI_ENABLE)
      WinSetTitle ($gui, "", "Stopped")

  EndSwitch

  Sleep (10)
WEnd

Func MyFunc ()
  ;This function might take hour to finish, so naturally I want to find an effective way to interrupt it
  HotKeySet ("{Esc}", "Terminate")

  While 1
    ;One loop of said function might take a minute or two to finish, while I need to interrupt it immediately upon request
    Sleep (10)
  WEnd

  HotKeySet ("{Esc}", "")
EndFunc

Func Terminate ()
  ;When interrupted I want to return to main loop, not exit app entirely
  If MsgBox (20, "", "Terminate?") = 6 Then Exit
EndFunc 

Few prerequisites that ideally I'd like to keep:

- I'm using MessageLoop mode and do not want use OnEvent.

- In actual script MyFunc () is launched from another function, not from main body if that's important.

- Stopping My Func () from GUI is not possible, it should be a hotkey > prompt dialog > yes or no.

- Waiting for finishing one pass in MyFunc () loop is not an option as it might take rather long, it should quit immediately.

Edited by mjolnirmarkiv

Share this post


Link to post
Share on other sites



If you want to exit out of a function, but not the script use a

Return
statement.

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Try this:

 

#include <GUIConstantsEx.au3>

Global $gui = GUICreate ("Stopped", 200, 70)
Global $run_button = GUICtrlCreateButton ("Run", 20, 20, 70, 30)
Global $exit_button = GUICtrlCreateButton ("Exit", 110, 20, 70, 30)

GUISetState (@SW_SHOW)

Global $gui_message, $bInterrupted = False

While $gui_message <> $exit_button
  $gui_message =  GUIGetMsg ()

  Switch $gui_message

    Case $run_button
      WinSetTitle ($gui, "", "Running...")
      GUICtrlSetState ($run_button, $GUI_DISABLE)
      GUICtrlSetState ($exit_button, $GUI_DISABLE)

      MyFunc ()

      GUICtrlSetState ($run_button, $GUI_ENABLE)
      GUICtrlSetState ($exit_button, $GUI_ENABLE)
      WinSetTitle ($gui, "", "Stopped")

  EndSwitch

  Sleep (10)
WEnd

Func MyFunc ()
  ;This function might take hour to finish, so naturally I want to find an effective way to interrupt it
  HotKeySet ("{Esc}", "Terminate")
  Local $iRet
  While True
    ;One loop of said function might take a minute or two to finish, while I need to interrupt it immediately upon request
    If $bInterrupted Then
        $iRet = MsgBox(4 + 32, "Question", "Do you want to terminate the process?")
        If $iRet = 6 Then
            ExitLoop
        Else
             $bInterrupted = False
        EndIf
    EndIf
    Sleep (50)
  WEnd
  HotKeySet ("{Esc}")
  If $bInterrupted Then MsgBox(0, "Test", "The function has been interrupted!", 30)
  $bInterrupted = False
EndFunc

Func Terminate ()
  ;When interrupted I want to return to main loop, not exit app entirely
  $bInterrupted = True
EndFunc

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Try this:

 

Br,

UEZ

 

And here's a problem "One loop of said function might take a minute or two to finish, while I need to interrupt it immediately upon request". Change that Sleep to whopping 60000 and that's how it'd function in a real life :)

Share this post


Link to post
Share on other sites

And here's a problem "One loop of said function might take a minute or two to finish, while I need to interrupt it immediately upon request". Change that Sleep to whopping 60000 and that's how it'd function in a real life :)

 

what are you trying to do that will take an hour to complete?


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Can you post that function which takes > 1 minute? Sleep() is not a good for a reproduction of your problem because Sleep() interrupts your script completely.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

mjolnirmarkiv,

 

;This function might take hour to finish, so naturally I want to find an effective way to interrupt it

;One loop of said function might take a minute or two to finish, while I need to interrupt it immediately upon request

As I say in the tutorial:

Remember that you must be in OnEvent mode and start the function from the main code - or have a function which checks internally whether it ought to allow an interruption

As you have effectively said that you can meet neither of those conditions, then I am afraid that you need to read the next line:

In all other cases you are not going to be able to interrupt your function

So you need to look elsewhere. :(

Perhaps you could run the long function as a separate script using an a3x file - then your main script remains active all the time and you can kill the other script when ever necessary. Depending on what exactly this function returns you may have to look into interprocess communication to get at it - but that is not overly difficult. Can you give us more details of what exactly you are doing - the more details the better we can help. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Can you post that function which takes > 1 minute? Sleep() is not a good for a reproduction of your problem because Sleep() interrupts your script completely.

Br,

UEZ

I could but it won't work if I won't post another over 2000 strings of code, basically there's a lot of WinWait's, ControlDoThis's and ControlDoThat's. Of course, I could insert a dozen of checks for $bInterruped in the loop, but I'm thinking of a more suitable solution.

Edited by mjolnirmarkiv

Share this post


Link to post
Share on other sites

If the problem can be solved by the simple insertion of a dozen of checks, you should choose this way at once  :)

Share this post


Link to post
Share on other sites

mjolnirmarkiv,

 

As I say in the tutorial:

As you have effectively said that you can meet neither of those conditions, then I am afraid that you need to read the next line:

So you need to look elsewhere. :(

Well, OnEvent might actualy work here, but I need to rethink the entire concept and leave some UIs for user to operate then. While right now I hide entire GUI and block user input except for Esc key when function is running. I'm not sure though if accelkeys assosiated with dummy controls will work if there's no GUI shown or it lost focus (and I need to focus on another app to operate it when this function runs).

 

Perhaps you could run the long function as a separate script using an a3x file - then your main script remains active all the time and you can kill the other script when ever necessary.

Thanks, will look into it.

Depending on what exactly this function returns you may have to look into interprocess communication to get at it - but that is not overly difficult.

Nothing in particular, either 1 and after demonstrating "Done" dialog box the script returns to idle loop, or 0 if some WinWait has reached its timeout and again returns to idle loop.

 

Can you give us more details of what exactly you are doing - the more details the better we can help. :)

The function is just doing some office work by setting up info in the database (I wish I'd have direct access to that database, but no, I had to operate that app with varrious ControlCommand's), which otherwise would have took gargantuan amount of time and nerve cells.

Share this post


Link to post
Share on other sites

mjolnirmarkiv,

Given that explanation I think a separate a3x file is definitely the way to go. Let me know if you need any help. :)

But a word of warning - what happens to your database if you suddenly halt the actions being taken upon it in mid-function? Do you not risk corrupting the data? :huh:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Yes, that's the way it seems... or checking for some boolean var every few lines in the loop :) I just wanted to check if I'm missing smth obvious here, so it may considered solved.

It might have corrupted smth if I've worked with database directly, which is not the case sadly. Since I'm doing it thought a client -- most definitely no, the user will just start from the place it has finished -- no problem.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0