ppat Posted February 6, 2009 Share Posted February 6, 2009 Is this possible in AutoIt?[do something] [in 3 minutes, launch this procedure: do_stuff(12,32)] [immediately continue to do something else without waiting for the 3 minutes] Func do_stuff($param1, $param2) EndFuncI know how to launch a Func after a certain given amount of time, usign loops. Basically, loops pause the script until the time is reached. I want something different: I want to program the launch of a function (with parameters) after a given time, but in the meantime continue to execute the script.Maybe AutoIt does not have this possibility to run "parallel threads". I recall using a programming language where this was possible, Javascript if I recall well.I guess the closest keyword would be "timer" and I could find _Timer_SetTimer in Autoit Help file. But a handle must be passed (no handle in my case), and callback functions do not accept parameters, so this is not exactly what I am looking for. Any suggestion? Link to comment Share on other sites More sharing options...
BrettF Posted February 6, 2009 Share Posted February 6, 2009 This has been asked many times, maybe search first? Multithreading is not a feature of AutoIt. The handle can be 0 if I remember rightly. Post your full code Cheers, Brett Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
ppat Posted February 6, 2009 Author Share Posted February 6, 2009 My code is: MsgBox(0, "Start", "Program start") ; I would like here and instruction: "Launch display_message("Hello", "Late execution") in 3 minutes from now MsgBox(0, "Last", "Last instruction in script") Func display_message($title, $message) MsgBox(0, $title, $message) EndFunc The expected behaviour is this: after pressing OK on "Program start", I would immediately get the dialogue "Last instruction in script" and 3 minutes after pressing the 1st OK, I would get the dialogue "Late execution" and the script would finish when I press OK on the dialogue "Late execution". You could call this multithreading, although in this precise example, there is no risk of collision. So, would you say it is possible? You know, it is very difficult to search in a forum that something is not possible! Having an expert opinion as yours would help tremendously. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 6, 2009 Moderators Share Posted February 6, 2009 ppat,You need to use TimerInit and TimerDiff:MsgBox(0, "Start", "Program start") $iBegin = TimerInit() MsgBox(0, "Last", "Last instruction in script") While 1 If TimerDiff($iBegin) > 5000 Then display_message("Hello", "Late execution"); For 3 minutes use 1000 * 60 * 3 WEnd Func display_message($title, $message) MsgBox(0, $title, $message) Exit EndFuncThis code starts timing from pressing "OK" on the "Program start" message box. If you want to time from the "Last instruction" message box, just move the $iBegin = TimerInit() line to after the MsgBox(0, "Last", "Last instruction in script") line.M23  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
BrettF Posted February 6, 2009 Share Posted February 6, 2009 Try this: MsgBox (0, "Start", "Script will start in 3 minutes") ;2 options Option 1 ;Sleep (3*1000*60);3 minutes (excuse my math if it isn't correct :) ;Option 2 $timer = TimerInit () While 1 If TimerDiff ($timer) >= 3*1000*60 Then display_message() ExitLoop Else Sleep (50) EndIf WEnd MsgBox(0, "Last", "Last instruction in script") Func display_message () MsgBox (0, "", "RAWR SAYS THE DINOSAUR!!!") EndFunc Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
KaFu Posted February 6, 2009 Share Posted February 6, 2009 (edited) I guess the closest keyword would be "timer" and I could find _Timer_SetTimer in Autoit Help file. But a handle must be passed (no handle in my case) As long as you don't compile your script explicitly as a command-line tool there is always a gui handle to pass: WinSetState(AutoItWinGetTitle(),'',@SW_SHOW) MsgBox(0,'','Title: ' & AutoItWinGetTitle() & @crlf & 'hWnd: ' & WinGetHandle(AutoItWinGetTitle())) and callback functions do not accept parameters Define the variables to use as global or read them from within the func. Best Regards Edited February 6, 2009 by KaFu  OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
ppat Posted February 6, 2009 Author Share Posted February 6, 2009 Thanks for both of your replies. It does not follow the course of events I wanted. "Last instruction in script" is not the last message. Melba23 is getting close. The problem is that if I take more than 3 minutes to press OK on "Last instruction in script", then display_message("Hello", "Late execution") will appear after more than 3 minutes. But at least it is close. I understand now that there is no multithreading in AutoIt 3. I assume there is in Javascript by design of the language. Anyway, although Melba23 is close, I cannot achieve what I want, because I want this: ; Main part of the program try_something(1,2) [Do many other instructions that may take more than 3 minutes to execute] Func try_something($a,$b) if a condition is not met then [Schedule a launch in 3 minutes of : try_something ($modifierd_a, $modified_b)] [Exit this func now and continue to process the instructions in the main part of this program] EndFunc Is this even possible in AutoIt3? Link to comment Share on other sites More sharing options...
BrettF Posted February 6, 2009 Share Posted February 6, 2009 MsgBox (0, "Start", "Script will start in 3 minutes") ;2 options Option 1 ;Sleep (3*1000*60);3 minutes (excuse my math if it isn't correct :) ;Option 2 $timer = TimerInit () While 1 If TimerDiff ($timer) >= 3000 Then; Use 3*1000*60 for 3 minutes $Exit = display_message() If $Exit Then ExitLoop Else $timer = TimerInit() EndIf Else Sleep (50) EndIf WEnd MsgBox(0, "Last", "Last instruction in script") Func display_message () $ret = MsgBox (4, "", "RAWR SAYS THE DINOSAUR!!!") If $ret = 6 Then $ExitTime = True Else $ExitTime = False EndIf Return $ExitTime EndFunc Cheers, Brett Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 6, 2009 Moderators Share Posted February 6, 2009 ppat,That is changing the goalposts in mid-game! I hate it when people do that!But AutoIt can still do it for you:Global $iCounter = 0 AdlibEnable("Counter", 1000) MsgBox(0, "Start", "Program start") ; This loop is eternal While 1 If GUIGetMsg() = - 3 Then Exit WEnd MsgBox(0, "Last", "Last instruction in script") Exit Func display_message($title, $message) MsgBox(0, $title, $message) Exit EndFunc Func Counter() $iCounter += 1 If $iCounter = 10 Then ; use 3 * 60 for 3 minutes - this is 10 seconds ; stop counting AdlibDisable() ; Show message display_message("Hello", "Late execution") EndIf EndFuncM23  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
bobchernow Posted February 6, 2009 Share Posted February 6, 2009 My code is: MsgBox(0, "Start", "Program start") ; I would like here and instruction: "Launch display_message("Hello", "Late execution") in 3 minutes from now MsgBox(0, "Last", "Last instruction in script") Func display_message($title, $message) MsgBox(0, $title, $message) EndFunc The expected behaviour is this: after pressing OK on "Program start", I would immediately get the dialogue "Last instruction in script" and 3 minutes after pressing the 1st OK, I would get the dialogue "Late execution" and the script would finish when I press OK on the dialogue "Late execution". You could call this multithreading, although in this precise example, there is no risk of collision. So, would you say it is possible? You know, it is very difficult to search in a forum that something is not possible! Having an expert opinion as yours would help tremendously. I am testing using globals and adlib. MsgBox(0, "Start", "Program start") Global $message = "Foo" Global $title = "Bar" AdlibEnable("display_message",30*1000) ; I would like here and instruction: "Launch display_message("Hello", "Late execution") in 3 minutes from now sleep(60*1000) MsgBox(0, "Last", "Last instruction in script") Func display_message() MsgBox(0, $title, $message) EndFunc It works. Sorta. The behavior is that after the initial msg, 30 seconds later the function pops. The script itself is just sleeping. I tried having the "last execution msg, but the msg seems to block the adlib message until it is dismissed. Try playing with adlib. Bob --------------------bobchernow, Bob ChernowWhat a long strange trip it's beenUDFs: [post="635594"]Multiple Monitor Screen Resolution Change[/post] Link to comment Share on other sites More sharing options...
ppat Posted February 6, 2009 Author Share Posted February 6, 2009 Bob, M23 and Brett, thanks for your replies. You pointed my attention to AdlibEnable, which looks promissing. The problem in your proposals is that MsgBox(0, "Last", "Last instruction in script") always come last, after closing the message that is postponed by 3 minutes. But I want the opposite: as soon as I press "OK" in the "Start" window, all following instructions should be immediately executed. "Last instruction in script" here means that it is the last instruction in the main section of the file, but actually the last instruction to be displayed is the one that has been postponed by 3 minutes. The help file says "The adlib function should be kept simple as it is executed often and during this time the main script is paused. ", but I notice that in practice, it keeps executing. Here is the code that is closest to what I want (slightly modified from M23) expandcollapse popupGlobal $iCounter = 0 MsgBox(0, "Start", "Program start") counter() MsgBox(0, "Last", "Last instruction in script") ; This loop is eternal While 1 WEnd Exit Func display_message($title, $message) MsgBox(0, $title, $message) Exit EndFunc Func Counter() AdlibDisable() $iCounter += 1 Sleep(2000); Simulate excuting tests for 2 seconds If $iCounter = 3 Then ; stop launching Counter after 3 runs ; Show message display_message("Hello", "Late execution") Else AdlibEnable("Counter", 2000) ; This will run Counter again after 2 seconds EndIf EndFunc This is what it does: after pressing "OK" on the start window, it launches Counter, does a few tests (simulated by the Sleep function). At 1st run, the condition is not met, so it relaunches the Counter function after 2 seconds. In the mean time, the program completes its execution ("Last instruction in script") and goes to the infinite loop. 2nd try for Counter, launched again 2 seconds after. 3rd try: this time the condition is met and says "Last execution". Only one thing bothers me with AdlibEnable: it calls every 250 ms (or time ms) the specified "function". Is there not instead a function that calls the specified "function" only once after 250 ms (or time ms) ? Link to comment Share on other sites More sharing options...
bobchernow Posted February 6, 2009 Share Posted February 6, 2009 I do not think there is one that only runs it once but you could force that by disabling the adlib function each time it runs, so it runs once and then it disables itself. Effectively that does what you want. Bob --------------------bobchernow, Bob ChernowWhat a long strange trip it's beenUDFs: [post="635594"]Multiple Monitor Screen Resolution Change[/post] Link to comment Share on other sites More sharing options...
KaFu Posted February 6, 2009 Share Posted February 6, 2009 One thing you have to keep in mind... msgbox() itself pauses the execution of the script! Thus if you build a timer to trigger something e.g. after 3 minutes and you have a msgbox() on screen for 5 minutes... the timer in the background keeps counting on, but the script can react earliest after the confirmation of the first msgbox(), meaning you'll get the trigger instantly after the first msgbox() is closed. Global $timer = TimerInit() AdlibEnable("timer") While 1 Switch MsgBox(3, 'Start', 'Do something' & @crlf & round((TimerDiff($timer)/1000),1)) Case 6 ; Yes MsgBox(0,'', 'Task done, timer reset' & @crlf & round((TimerDiff($timer)/1000),1)) $timer = TimerInit() Case 7 ; No MsgBox(0,'', 'Task not done, timer not reset' & @crlf & round((TimerDiff($timer)/1000),1)) Case Else ; 2 = Cancel... and everything else ExitLoop EndSwitch sleep(10) WEnd MsgBox(0, "Last", "Last instruction in script") Func Timer() If TimerDiff($timer) > 10000 Then MsgBox(0, '', 'Fallen asleep?') $timer = TimerInit() EndIf EndFunc ;==>timer If you want to utilize msgbox() AND want to have triggered an event while old msgbox() is still open... write timestamp to ini-file and use a second (background) script to monitor that ini-file and pop-up a reminder. Â OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26)Â BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16)Â ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 6, 2009 Moderators Share Posted February 6, 2009 ppat,You have again changed those goal posts in mid-match.If I understand correctly (which given the earlier attempts seems unlikely!), you want to run a number of commands between "Program start" and "Last instruction in script" - then, when this finishes, wait until a specified time before running the "Late execution" code. Nothing else need happen between "Last instruction in script" and the "Late execution" code. However, if the "Program start" to "Last instruction in script" takes longer than the specified time, you want the "Late execution" code to run anyway at that point and then return to the "Program start" to "Last instruction in script" code to finish it.If that is what you want then this will do that for you:expandcollapse popupGlobal $iCounter = 0 Global $fEnded = False Global $fLate_Ended = False AdlibEnable("Counter", 1000) MsgBox(0, "Start", "Program start") Sleep(20 * 1000) ; sleep to sumulate the code here MsgBox(0, "Last", "Last instruction in script") If $fLate_Ended Then Exit $fEnded = True ; This loop is eternal While 1 Sleep(100) WEnd Func display_message($title, $message) MsgBox(0, $title, $message) If $fEnded Then Exit EndFunc Func Counter() $iCounter += 1 If $iCounter = 10 Then ; use 3 * 60 for 3 minutes - this is 10 seconds ; stop counting AdlibDisable() ; Show message display_message("Hello", "Late execution") $fLate_Ended = True EndIf EndFuncAlter the value in the Sleep command and you will see that script only ends when BOTH the "Program start" to "Last instruction in script" code AND the "Late execution" code have finished.I hope I have understood correctly - but change the goal-posts again and you are on your own my friend! ;-)M23  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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
ppat Posted February 10, 2009 Author Share Posted February 10, 2009 Thank you all, I now have an answer to my question. The key was AdlibEnable which schedules a launch of a function repetitively at a certain frequency until AdlibDisable is called. To achieve sort of "parallel threads", I wrap up the code in an au3 file and execute this file from the main code which is in an other au3 file. The main file continues to execute, while the sub file waits for the late execution, in parallel.Thanks, subject closed. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now