Developers Jos Posted September 24, 2022 Developers Posted September 24, 2022 I guess all i was trying to tell you is that you should always end the loop when reading the stdout has an error. The others tests shouldn't be needed. SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past.
VAN0 Posted September 26, 2022 Author Posted September 26, 2022 (edited) @Jos, exactly, that's why this topic created - without other tests it hangs the script... There might be something wrong with StdoutRead()... every time it used it increases number of handles: #include <Misc.au3> Local $iSleep = 0 ; <==== if set to 1 it will not timeout Local $iTimeout = 1000000 / ($iSleep * 10000 + 1), $iPrevTimer = 0 While 1 If TimerDiff($iPrevTimer) > 1000 Then Local $sOut = "", $i = 0 $iPrevTimer = TimerInit() Local $iPID = Run(@ComSpec & " /c WMIC PROCESS WHERE Name='autoit3.exe' GET handlecount", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ConsoleWrite(StringLeft("PID=" & ProcessExists($iPID) & " ", 11)) Do $i += 1 Sleep($iSleep) $sOut &= StdoutRead($iPID) Until @error Or $i > $iTimeout StdioClose($iPID) Local $iClose = ProcessClose($iPID) ConsoleWrite(" loops=" & StringLeft($i & " ", 8) & " close=" & $iClose & " error=" & @error & " out=" & StringStripWS($sOut, 4) & @CRLF) EndIf Sleep(100) WEnd Another thing, if Sleep(1) added into the loop, the issue seems to disappear, at least in my test without sleep it starts timeout after few seconds Spoiler >Running:(3.3.16.1):E:\Program Files\AutoIt3\autoit3.exe "E:\Program Files\AutoIt3\Scripts\vpn\test.au3" PID=119360 loops=80518 close=0 error=0 out=HandleCount 198 200 166 PID=94344 loops=79281 close=0 error=0 out=HandleCount 198 202 166 PID=30020 loops=80421 close=0 error=0 out=HandleCount 198 204 166 PID=125568 loops=1000001 close=0 error=0 out= PID=81012 loops=1000001 close=0 error=0 out= with Sleep(1) it hasn't timeout yet. Edited September 26, 2022 by VAN0
HurleyShanabarger Posted September 26, 2022 Posted September 26, 2022 The minimum sleep time is 10 milliseconds, if you choose a value lower it will still be around at least 10ms. #Region Main _ExecBatch("rasdial", 10) Func _ExecBatch($sCmd, $iCnt) Local Enum $ePid = 0, $eRslt, $eMax Local $arExec[$iCnt][$eMax] ; Process: start For $iExec = 0 To $iCnt - 1 $arExec[$iExec][$ePid] = Run($sCmd, "", @SW_HIDE, $STDOUT_CHILD) Next ; Process: wait Local $iActive = 0 Do $iActive = 0 For $iExec = 0 To $iCnt - 1 If ProcessExists($arExec[$iExec][$ePid]) Then $iActive += 1 Next Until $iActive = 0 ; Process: get data Local $iErrorCount = 0 For $iExec = 0 To $iCnt - 1 $arExec[$iExec][$eRslt] = StdoutRead($arExec[$iExec][$ePid]) If @error Then $iErrorCount += 1 StdioClose($arExec[$iExec][$ePid]) ; not sure if required Next ; Display data ;_ArrayDisplay($arExec) ConsoleWrite("Errors: " & $iErrorCount & @CRLF) EndFunc ;==>_ExecBatch #EndRegion Main Can you try this approach? This will start rasdial 10 times (change it to any value you like) and will wait until all process are closed and will than read the data afterwards. I did run this for an hour without an issue and had 50 process startet at the same time.
VAN0 Posted September 26, 2022 Author Posted September 26, 2022 @HurleyShanabarger The "process wait" loop exits when one process is still running, not when all of them are closed. And besides, as per original post, it works without issue when waited for the process to close. Anyway, would you mind test code from my previous post, if you can reproduce the issue too? It's reproducible on my machine 100% after just a few seconds of running it. At this point I'm not trying find a work around the issue but determine what actually causing it.
HurleyShanabarger Posted September 27, 2022 Posted September 27, 2022 I am pretty sure that the Process: wait loop is only left, when there is no process running anymore, that was started in the Process: start loop. Maybe you can explain that to me. No really sure, what code I should run and test. The one from this post is running. Best to provide a full script with instructions for testing. Your script that is using WMIC is reading the handle count for all autoit3.exe processes. When running a script there should be some handles from the AutoIt wrapper. I changed my script, and it seems that not all handles are closed/released. But that still does not mean something is wrong with StdoutRead. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #Tidy_Parameters=/reel /sf /ri #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Region Main #include <Constants.au3> For $iExex = 1 To 10 _ExecBatch("rasdial.exe", 10) Next Func _ExecBatch($sCmd, $iCnt) Local Enum $ePid = 0, $eRslt, $eMax Local $arExec[$iCnt][$eMax] ; Process: start RunWait(@ComSpec & " /c WMIC PROCESS WHERE ProcessId=" & @AutoItPID & " GET handlecount >Handle_1_BeforeProcessStarted.txt", @TempDir, @SW_HIDE) For $iExec = 0 To $iCnt - 1 $arExec[$iExec][$ePid] = Run($sCmd, "", @SW_HIDE, $STDOUT_CHILD) Next ; Process: wait RunWait(@ComSpec & " /c WMIC PROCESS WHERE ProcessId=" & @AutoItPID & " GET handlecount >Handle_2_AfterProcessStarted.txt", @TempDir, @SW_HIDE) Local $iActive = 0 Do $iActive = 0 For $iExec = 0 To $iCnt - 1 If ProcessExists($arExec[$iExec][$ePid]) Then $iActive += 1 Next Until $iActive = 0 RunWait(@ComSpec & " /c WMIC PROCESS WHERE ProcessId=" & @AutoItPID & " GET handlecount >Handle_3_AfterProcessClosed.txt", @TempDir, @SW_HIDE) ; Process: get data Local $iErrorCount = 0 For $iExec = 0 To $iCnt - 1 $arExec[$iExec][$eRslt] = StdoutRead($arExec[$iExec][$ePid]) If @error Then $iErrorCount += 1 StdioClose($arExec[$iExec][$ePid]) ; not sure if required Next RunWait(@ComSpec & " /c WMIC PROCESS WHERE ProcessId=" & @AutoItPID & " GET handlecount >Handle_4_AfterStdoutRead.txt", @TempDir, @SW_HIDE) ; Display data ConsoleWrite("Errors: " & $iErrorCount & @CRLF) ConsoleWrite("Handle_1_BeforeProcessStarted:" & @TAB & StringReplace(FileRead(@TempDir & "\Handle_1_BeforeProcessStarted.txt"), @CRLF, "") & @CRLF) ConsoleWrite("Handle_2_AfterProcessStarted: " & @TAB & StringReplace(FileRead(@TempDir & "\Handle_2_AfterProcessStarted.txt"), @CRLF, "") & @CRLF) ConsoleWrite("Handle_3_AfterProcessClosed: " & @TAB & StringReplace(FileRead(@TempDir & "\Handle_3_AfterProcessClosed.txt"), @CRLF, "") & @CRLF) ConsoleWrite("Handle_4_AfterStdoutRead: " & @TAB & StringReplace(FileRead(@TempDir & "\Handle_4_AfterStdoutRead.txt"), @CRLF, "") & @CRLF) ConsoleWrite("---------------------------------" & @CRLF) FileDelete(@TempDir & "\Handle_1_BeforeProcessStarted.txt") FileDelete(@TempDir & "\Handle_2_AfterProcessStarted.txt") FileDelete(@TempDir & "\Handle_3_AfterProcessClosed.txt") FileDelete(@TempDir & "\Handle_4_AfterStdoutRead.txt") EndFunc ;==>_ExecBatch #EndRegion Main I am using @AutoItPid to just get the handles of the current process, my result looks like this expandcollapse popupErrors: 0 Handle_1_BeforeProcessStarted: HandleCount 163 Handle_2_AfterProcessStarted: HandleCount 194 Handle_3_AfterProcessClosed: HandleCount 194 Handle_4_AfterStdoutRead: HandleCount 174 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 174 Handle_2_AfterProcessStarted: HandleCount 204 Handle_3_AfterProcessClosed: HandleCount 204 Handle_4_AfterStdoutRead: HandleCount 184 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 184 Handle_2_AfterProcessStarted: HandleCount 214 Handle_3_AfterProcessClosed: HandleCount 214 Handle_4_AfterStdoutRead: HandleCount 194 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 194 Handle_2_AfterProcessStarted: HandleCount 224 Handle_3_AfterProcessClosed: HandleCount 224 Handle_4_AfterStdoutRead: HandleCount 204 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 204 Handle_2_AfterProcessStarted: HandleCount 234 Handle_3_AfterProcessClosed: HandleCount 234 Handle_4_AfterStdoutRead: HandleCount 214 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 214 Handle_2_AfterProcessStarted: HandleCount 244 Handle_3_AfterProcessClosed: HandleCount 244 Handle_4_AfterStdoutRead: HandleCount 224 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 224 Handle_2_AfterProcessStarted: HandleCount 254 Handle_3_AfterProcessClosed: HandleCount 254 Handle_4_AfterStdoutRead: HandleCount 234 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 234 Handle_2_AfterProcessStarted: HandleCount 264 Handle_3_AfterProcessClosed: HandleCount 264 Handle_4_AfterStdoutRead: HandleCount 244 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 244 Handle_2_AfterProcessStarted: HandleCount 274 Handle_3_AfterProcessClosed: HandleCount 274 Handle_4_AfterStdoutRead: HandleCount 254 --------------------------------- Errors: 0 Handle_1_BeforeProcessStarted: HandleCount 254 Handle_2_AfterProcessStarted: HandleCount 284 Handle_3_AfterProcessClosed: HandleCount 284 Handle_4_AfterStdoutRead: HandleCount 264 ---------------------------------
VAN0 Posted September 27, 2022 Author Posted September 27, 2022 38 minutes ago, HurleyShanabarger said: I am pretty sure that the Process: wait loop is only left, when there is no process running anymore, that was started in the Process: start loop. Maybe you can explain that to me. The If condition in the loop checks if process still exists, not if process doesn't exist. But that's half the issue, when one of the processes still exists it sets $iActive to non-zero, and the loop exits if $iActive is non-zero. It should've been checked if $iActive is equal to $iCnt 38 minutes ago, HurleyShanabarger said: No really sure, what code I should run and test. The one from this post Yes, unchanged code with WMIC, the out= should have numbers unless it's timedout
HurleyShanabarger Posted September 27, 2022 Posted September 27, 2022 Can you point to the part, where the outer loop exits if $iActive is non zero?
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