Sign in to follow this  
Followers 0
autoitter

Synchronization between events and main loop

3 posts in this topic

Hi all,

Most of the time I use the OnEvent mode for my GUI scripts. Now I was wondering a what moments an event like a button press can interrupt the main loop. I wrote a small test script:

AutoItSetOption("MustDeclareVars", 1)
 
 #include <ButtonConstants.au3>
 #include <GUIConstantsEx.au3>
 #include <WindowsConstants.au3>
 
 Opt("GUIOnEventMode", 1)
 #Region ### START Koda GUI section ### Form=C:\AutoItProjects\TestOnEvent\TestOnEvent.kxf
 Global $MainForm = GUICreate("Test", 253, 160, -1, -1)
 GUISetOnEvent($GUI_EVENT_CLOSE, "MainFormClose")
 Global $Button1 = GUICtrlCreateButton("Button1", 80, 57, 100, 33, 0)
 GUICtrlSetOnEvent(-1, "Button1Click")
 GUISetState(@SW_SHOW)
 #EndRegion ### END Koda GUI section ###
 
 Global $i, $j
 
 While 1
     For $i = 1 To 10000
         For $j = 1 To 10000
         Next
     Next
     ConsoleWrite("Looping..." & @CRLF)
     Sleep(1000)
 WEnd
 
 Func Button1Click()
     ConsoleWrite("I=" & $i & @CRLF)
     ConsoleWrite("J=" & $j & @CRLF)
 EndFunc
 
 Func MainFormClose()
     Exit
 EndFunc

When this script is executed you see that an event like pressing a button can interrupt anywhere in the For-loop and not only when the main loop is calling Sleep(). But can it also interrupt in the middle of a call to a function, or for example in the middle of a DllCall()?

So if I do processing in the main loop, do I have to take certain actions to keep it "thread save"?

Share this post


Link to post
Share on other sites



might want to protect for something like that...

AutoItSetOption("MustDeclareVars", 1)

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=C:\AutoItProjects\TestOnEvent\TestOnEvent.kxf
Global $MainForm = GUICreate("Test", 253, 160, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "MainFormClose")
Global $Button1 = GUICtrlCreateButton("Button1", 80, 57, 100, 33, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Global $i, $j

While 1
    
    ; disable button
    GUICtrlSetOnEvent($Button1, "")
    ToolTip("Button disabled", 10, 10)
    For $i = 1 To 5000
         For $j = 1 To 5000
         Next
     Next
     ConsoleWrite("Looping #1..." & @CRLF)
    ; enable button
    GUICtrlSetOnEvent($Button1, "Button1Click")
    ToolTip("Button enabled", 10, 10)
     For $i = 1 To 5000
         For $j = 1 To 5000
         Next
     Next
     ConsoleWrite("Looping #2..." & @CRLF)
     Sleep(1000)
WEnd

Func Button1Click()
     ConsoleWrite("I=" & $i & @CRLF)
     ConsoleWrite("J=" & $j & @CRLF)
EndFunc

Func MainFormClose()
     Exit
EndFunc

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

Well that's a solution :-)

The only disadvantage of this approach is that button clicks are sometimes lost. Probably the best thing to do is to have the event handlers set some flag and act upon that in the main loop.

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