Jump to content

Using AdLibEnable to interrupt one function in favor of another


Recommended Posts

Hello all,

I'm trying to use AdLibEnable to time how long a function runs. If the function runs too long, I want my script to stop that function and move on to the next function that needs to be called.

Below is a script that models what I need to do. Basically, the main function of the script is to go through the steps in the array $aSteps one at a time. Each "step" is just a function that counts for a specific period of time (5, 10, or 20 seconds). If one of those functions - namely, the TwentySeconds function- runs for more than 15 seconds, I want to stop that function and have the script move on to the next one as determined by $aSteps

When I run the code below, AdLibEnable properly interrupts the processing of the function TwentySeconds but the function continues in the background because I eventually get the 20 seconds, time's up MsgBox and my $i goes up one increment too high because I get a "Array variable has incorrect number of subscripts or subscript dimension range exceeded." error.

I'm not sure what I need to do next and I'm admittedly a bit cross-eyed from looking at this for so long. Any ideas? Thanks in advance! Please let me know if I can clarify anything.

Kate

#include <Array.au3>

Dim $FunctionRunTime
Global $i=0
$aSteps=_ArrayCreate("Step1","Step2","Step3")

FileProcessor(0)

Func FileProcessor($StartingRecord)
$i=$StartingRecord
    Do
        Select
            Case $aSteps[$i]="Step1"
                FiveSeconds()
            Case $aSteps[$i]="Step2"
                TwentySeconds()
            Case $aSteps[$i]="Step3"
                TenSeconds()
            Case $aSteps[$i]="Step4"
                FiveSeconds()
        EndSelect
        $i=$i+1
    Until $i=UBound($aSteps)
EndFunc

Func FiveSeconds()
    $FunctionRunTime=0
    AdlibEnable("ForceNextFile")
    MsgBox(0,"Start","I will count silently for 5 seconds")
    Sleep(5000)
    MsgBox(0,"End","5 seconds, time's up")
    AdlibDisable()
EndFunc

Func TenSeconds()
    $FunctionRunTime=0
    AdlibEnable("ForceNextFile")
    MsgBox(0,"Start","I will count silently for 10 seconds")
    Sleep(10000)
    MsgBox(0,"End","10 seconds, time's up")
    AdlibDisable()
EndFunc

Func TwentySeconds()
    $FunctionRunTime=0
    AdlibEnable("ForceNextFile")
    MsgBox(0,"Start","I will count silently for 20 seconds")
    Sleep(20000)
    MsgBox(0,"End","20 seconds, time's up")
    AdlibDisable()
EndFunc

Func ForceNextFile()
    $FunctionRunTime=$FunctionRunTime+250
    If $FunctionRunTime>=15000 Then
        MsgBox(0,"error","function exceeded 15 seconds of run time")
        $i=$i+1
        If $i<=(UBound($aSteps)-1) Then
            FileProcessor($i)
        ElseIf $i>(UBound($aSteps)-1) Then
            Exit
        EndIf
    EndIf
EndFunc
Link to comment
Share on other sites

Your script doesn't work because of two main reasons $FunctionRunTime is always set to 0 and 250 when ForceNextFile is call. On Until $i=UBound($aSteps) should be Until $i=UBound($aSteps) - 1 to run your script.

AdlibEnable("ForceNextFile") is called and executed after 250 mmsec, those you have a open end to your code making it use TONs of memory. Also the $i there is no resetting it back to 0 or immediate exit if you go to high. If may work the first time but on the returning back on the last one it catches a "Array variable has incorrect number of subscripts or subscript dimension range exceeded." error again

Editted - I see now AdlibEnable does work still doing the loopback on number 2

Edited by TerarinK

0x576520616C6C206469652C206C697665206C69666520617320696620796F75207765726520696E20746865206C617374207365636F6E642E

Link to comment
Share on other sites

  • Moderators

kate,

Have a look at this. It is substantially different to your script, but for good reasons.

The main difference is in the way I have used Adlib to check the timing. You had Sleep statements in the timed functions - during this time the script is non-responsive and it makes it very difficult to break out of the function via Adlib. As you can see, I have introduced loops which continually look for a flag (set by the Adlib function) showing it is time to stop. The Adlib function merely acts as a timer and then sets the flag - good practice to keep the Adlib as short as possible because it prevents the main script from running while it is being run.

Global $fFlag = False, $iTime, $iAdlibTimer
Global $aSteps[4] = [5, 20, 10, 5]

FileProcessor()

Func FileProcessor()
    
    For $i = 0 to 3
        _Seconds($aSteps[$i])
    Next
EndFunc

Func _Seconds($iTime)
    $fFlag = False
    $iBegin = TimerInit()
    $iAdlibTimer = $iBegin
    AdlibEnable("_ForceNext")
    While Timerdiff($iBegin) < $iTime * 1000
        Sleep(100)
        If $fFlag Then ExitLoop
    WEnd
    If $fFlag Then
        ConsoleWrite("Cutting short at 15 Secs" & @CRLF)
    Else
        ConsoleWrite("Ran through to " & $iTime & " secs" & @CRLF)
    EndIf
    AdlibDisable()
EndFunc

Func _ForceNext()
    If TimerDiff($iAdlibTimer) > 15000 Then $fFlag = True
EndFunc

There are other changes - but I am sure you can see the underlying principles here. However, please ask if anything is unclear.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see 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

 

Link to comment
Share on other sites

Hey Melba23,

I think you touched on the heart of my issue which is that I need to break out of a function when the script is non-responsive. One of the functions in my real life script (the example I posted was a scaled down simulation of the real one) is getting stuck randomly and I'm not sure why or where or even which function is hanging. The script runs overnight unattended and it is shut down by Windows Task Manager if it runs too long so that makes troubleshooting difficult.

My first thought was to time the functions to see how long they run. Each of the functions in the real life script should take 60 seconds or less to run and I thought if I had some way of knowing which function was hanging, I'd be able to troubleshoot it. The reason I created the simulation script I posted is that I'd not only like to know what function is hanging, I'd also like the script to terminate that function and move on to the next one.

This is one of those times when I really miss GOTO!!! And I'm not meaning to be cryptic about my real life script, it's just that there's a ton of stuff that the script needs to do and I don't want to bore everyone here with it. Maybe I can post relevant sections if that would help explain what I'm trying to do.

I don't know, perhaps I am taking the wrong approach to my troubleshooting...is there something besides AdLibEnable that I should look into using? Something that will terminate a non-responsive function?

Thanks,

Kate

Link to comment
Share on other sites

Your script doesn't work because of two main reasons $FunctionRunTime is always set to 0 and 250 when ForceNextFile is call. On Until $i=UBound($aSteps) should be Until $i=UBound($aSteps) - 1 to run your script.

AdlibEnable("ForceNextFile") is called and executed after 250 mmsec, those you have a open end to your code making it use TONs of memory. Also the $i there is no resetting it back to 0 or immediate exit if you go to high. If may work the first time but on the returning back on the last one it catches a "Array variable has incorrect number of subscripts or subscript dimension range exceeded." error again

Editted - I see now AdlibEnable does work still doing the loopback on number 2

Hi Teraink,

I'm confused. I set $FunctionRunTime to 0 before AdLib is enabled because I don't want any of the previous values to carry over. Each function needs to be timed independently, not cumulatively with the other functions.

I do have logic to exit the script if $i goes too high, it's on Line 60. Is my logic on that line incorrect? I'm don't want there to be an open ended loop, I want the script to either call the FileProcessor function or exit based on the value of $i.

You're right about Until $i=UBound($aSteps) - 1 but I still get the incorrect number of subscripts error after making that change.

Thanks,

Kate

Edited by Kate
Link to comment
Share on other sites

  • Moderators

Kate,

Take a look at this thread - it deals with a similar sort of problem to the one you are dealing with and some of the suggestions there might help you. In particular it shows a way of determining whether a process is "hanging" and using Adlib to close it.

Again, come back if there is anything that is unclear.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see 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

 

Link to comment
Share on other sites

... Each of the functions in the real life script should take 60 seconds or less to run ...

Then there must be a reason why you just cannot watch it run as an au3 text file with

AutoItSetOption("TrayIconDebug", 1) ;0-off

set to allow you to know the line that it hangs on :-)

If you cannot mouse over the AutoIt icon to get that info then you might sprinkle several of these around:

_FileWriteLog

I've had this thread open all day - just have not had the chance to get back to it...

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Kate,

Take a look at this thread - it deals with a similar sort of problem to the one you are dealing with and some of the suggestions there might help you. In particular it shows a way of determining whether a process is "hanging" and using Adlib to close it.

Again, come back if there is anything that is unclear.

M23

Ah! I think I get it! I think I can design a sort of hybrid of your script, my script and the concepts in the list you posted will do what I need. Unfortunately, I'm heading out of town, but I will come back if I have any other questions.

Thanks for your advice!

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...