Jump to content
jugador

_WinAPI_WaitForMultipleObjects

Recommended Posts

Posted (edited)

_WinAPI_WaitForSingleObject (- Waits until the specified object is in the signaled state)
_WinAPI_WaitForMultipleObjects (- Waits until one or all of the specified objects are in the signaled state)

How to rewrite this code using  _WinAPI_WaitForMultipleObjects

 

& how to do.....
if {ESC} IsPressed then Exit process will be on hold
until __ReadData or __WriteData which ever process is running is complete / timeout.

;~ How to rewrite this code using _WinAPI_WaitForMultipleObjects
#include <Date.au3>
HotKeySet("{ESC}", "_Exit")

Example()
Func Example()
    Local $Loop_toRun = 10
    Local $GetData
    Local $i = 0
    Do
        sleep(250)
        ConsoleWrite("> " & $i & ") Data download started time " & _NowTime() & @CRLF)
        $GetData = __ReadData()
        ConsoleWrite("> " & $i & ") Data download done " & _NowTime() & @CRLF)
        __WriteData($GetData, $i)
        $i = $i + 1
    Until $i = $Loop_toRun
EndFunc

Func __ReadData()
    Local $dData = InetRead("https://www.autoitscript.com/forum/")
    Local $sData = BinaryToString($dData)
    sleep(2000)     ;~ intentional sleep to delay the process
    Return $sData
EndFunc

Func __WriteData($GtData, $i)
    ConsoleWrite("+ " & $i & ") writing Data.... " & _NowTime() & @CRLF)
    Local $WData = $GtData & @CRLF
    Local $sFilePath = @ScriptDir & '\test' & $i & '.txt'
    Local $hFileOpen = FileOpen($sFilePath, 1)
    sleep(5000)     ;~ intentional sleep to delay the process
    FileWrite($hFileOpen, $WData)
    FileClose($hFileOpen)
    ConsoleWrite("+ " & $i & ") writing complete " & _NowTime() & @CRLF)
EndFunc

Func _Exit()
    Exit
EndFunc ;==>

 

Edited by jugador

Share this post


Link to post
Share on other sites

So, I’m not sure why you want to use _WinWaitMultipleObjects here, is there some other process contended for a shared resource?

Anyway, I think what you want can be achieved fairly easily with these mods(not tested).

I’ve made it wait until the write is done, no matter whether it’s interrupted in the read or write.  Only because it didn’t make sense to wait for the read to finish only to kill it without saving.  But if that’s what you want you can put a check at the end of read, like the one after write.

;~ How to rewrite this code using _WinAPI_WaitForMultipleObjects
#include <Date.au3>
HotKeySet("{ESC}", "_Exit")

Global $bFinished=True, $bMustExit=False

Example()
Func Example()
    Local $Loop_toRun = 10
    Local $GetData
    Local $i = 0
    Do
        sleep(250)
        ConsoleWrite("> " & $i & ") Data download started time " & _NowTime() & @CRLF)
        $GetData = __ReadData() 
        ConsoleWrite("> " & $i & ") Data download done " & _NowTime() & @CRLF)
        __WriteData($GetData, $i)
        $i = $i + 1
    Until $i = $Loop_toRun
EndFunc

Func __ReadData()
    $bFinished=False
    Local $dData = InetRead("https://www.autoitscript.com/forum/")
    Local $sData = BinaryToString($dData)
    sleep(2000)     ;~ intentional sleep to delay the process
   
    Return $sData
EndFunc

Func __WriteData($GtData, $i)
    ConsoleWrite("+ " & $i & ") writing Data.... " & _NowTime() & @CRLF)
    Local $WData = $GtData & @CRLF
    Local $sFilePath = @ScriptDir & '\test' & $i & '.txt'
    Local $hFileOpen = FileOpen($sFilePath, 1)
    sleep(5000)     ;~ intentional sleep to delay the process
    FileWrite($hFileOpen, $WData)
    FileClose($hFileOpen)
    ConsoleWrite("+ " & $i & ") writing complete " & _NowTime() & @CRLF)
    $bFinished=True
    If $bMustExit Then _Exit()
EndFunc

Func _Exit()
   If $bFinished Then Exit
   $bMustExit=True
EndFunc ;==>

 


Code hard, but don’t hard code...

Share this post


Link to post
Share on other sites
Posted (edited)

@JockoDundee it's just an example
I want to learn how to use _WinAPI_WaitForMultipleObjects with _WinAPI_CreateEvent & _WinAPI_WaitForSingleObject effectively.

Edited by jugador

Share this post


Link to post
Share on other sites
Posted (edited)

@jugador  See my Named Pipe IPC UDF in my signature for a complete example of the usage of _WinAPI_WaitForMultipleObjects with _WinAPI_CreateEvent.  The basis is to use overlapped option of WinAPI (or other similar functions). Let me know if you have further questions.

Edited by Nine

Share this post


Link to post
Share on other sites
12 hours ago, jugador said:

it's just an example

I think you may want to use a better example - Autoit is not multi-threaded - therefore you need to test with a multi-process example.
 @Nine’s Named Pipe is an example of IPC - InterProcessCommunication.

Not to say that a single working program can’t somehow use WaitForMultipleObjects, if one is determined, it’s just that there is usually an easier way.


Code hard, but don’t hard code...

Share this post


Link to post
Share on other sites
Posted (edited)

@JockoDundee Just to start with basic I put this example. Instead of two different function think as two different programs

@Nine Need more time to understand your code properly

Anyways Guys if any error in coding please do mention.

#include <Date.au3>
#include <WinAPIHObj.au3>
#include <WinAPIProc.au3>

HotKeySet("{ESC}", "_Exit")

Global $Esc_isTrue = False
Global $g_tEvents = DllStructCreate("handle Event[2];")
$g_tEvents.Event(1) = _WinAPI_CreateEvent(0, True, False)
$g_tEvents.Event(2) = _WinAPI_CreateEvent(0, True, False)

Example()

Func Example()
    Local $Loop_toRun = 5
    Local $GetData
    Local $iEvent
    Local $i = 0
    Do
        sleep(250)
        If _WinAPI_WaitForSingleObject($g_tEvents.Event(2), 0) <> 0 Then
            $GetData = __ReadData()
        Else
            ConsoleWrite("2nd Process closing error" & @CRLF)
            Exit
        Endif

        $iEvent = _WinAPI_WaitForMultipleObjects(2, $g_tEvents, False, 100)
        Switch $iEvent
            Case 0
                _WinAPI_ResetEvent($g_tEvents.Event(1))
                If $Esc_isTrue = True Then _Exit()
                __WriteData($GetData, $i)
            Case -1 ;Error
                Exit
        EndSwitch
        If $Esc_isTrue = True Then _Exit()
        $i = $i + 1
    Until $i = $Loop_toRun

$Esc_isTrue = True
_Exit()
EndFunc   ;==>Example

Func __ReadData()
    _WinAPI_SetEvent($g_tEvents.Event(1))
    ConsoleWrite("> ) Data download started time " & _NowTime() & @CRLF)
    Local $dData = InetRead("https://www.autoitscript.com/forum/")
    Local $sData = BinaryToString($dData)
    sleep(3000)
    ConsoleWrite("> ) Data download end time " & _NowTime() & @CRLF)
    Return $sData
EndFunc   ;==>Example

Func __WriteData($GtData, $i)
    _WinAPI_SetEvent($g_tEvents.Event(2))
    ConsoleWrite("+ " & $i & ") writing Data.... " & _NowTime() & @CRLF)
    Local $WData = $GtData & @CRLF
    Local $sFilePath = @ScriptDir & '\test' & $i & '.txt'
    Local $hFileOpen = FileOpen($sFilePath, 1)
    FileWrite($hFileOpen, $WData)
    FileClose($hFileOpen)
    sleep(3000)
    ConsoleWrite("+ " & $i & ") writing complete " & _NowTime() & @CRLF)
    _WinAPI_ResetEvent($g_tEvents.Event(2))
EndFunc   ;==>Example

Func _Exit()
    If $Esc_isTrue = False Then
        $Esc_isTrue = True
        Return
    Endif
    _WinAPI_CloseHandle($g_tEvents.Event(1))
    _WinAPI_CloseHandle($g_tEvents.Event(2))
    Exit
EndFunc ;==>

 

Edited by jugador

Share this post


Link to post
Share on other sites

As far as I can see (I did not test your script), there is no obvious flaw in your code.  However, I do not see the advantage of using events (but there is not harm doing so).  Normal usage of events is to launch an overlapped function, and while that function is working you are free to do something else.  When the overlapped function is completed, it is signaled as an event and you can react to it.

Currently your code set manually events, because you are not using overlapped functions.  You could do the same with global variables.  But like I said, there is no harm doing it that way.

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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...