Что нового

При работе скрипта часто выскакивает ошибка

Can

Новичок
Сообщения
59
Репутация
1
Здравствуйте.
Подскажите пожалуйста, почему часто при работе скрипта выскакивает ошибка,
иногда через 8 часов, а иногда через 30 минут?

Сама ошибка: Line -1:

Error: Recursion level has been exceeded - Autoit will to prevent
stack owerflov.



Сам скрипт очень большой, приведу пример частично, может чего добавить к нему надо?


Код:
HotKeySet ( "{ESC}" ,"_Exit")
Global $i1,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10,$t11,$t12,$t13,$t14,$t15,$t16,$t17,$t18,$t19,$t20
Global $w1,$w2,$w3,$w4,$w5,$w6,$w7,$w8,$w9,$w10,$w11,$w12,$w13,$w14,$w15,$w16,$w17;$o1
Global $d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8;$d9,$d10,$d11,$d12,$d13,$d14,$d15
Global $z1

$z1=1
While $z1 <= 1
  
   
   Cycle1()  
   Cycle2()  
   Cycle3()  
   Cycle4()  
   Cycle5()   
   Cycle6()  
   Cycle7()  
   Cycle8()  
   Cycle9()  
   Cycle10() 
   Cycle11() 
   Cycle12() 
   Cycle13() 
   Cycle14() 
   Cycle15()
   Cycle16()  
   Cycle17()  
   Cycle18()  
   Cycle19()  
   Cycle20()   
   ;Cycle21()  
   ;Cycle22()  
   ;Cycle23()  
   ;Cycle24()  
   ;Cycle25() 
   ;Cycle26() 
   ;Cycle27() 
   ;Cycle28() 
   ;Cycle29() 
   ;Cycle30()

   Cycle41()  
   Cycle42()  
   Cycle43()  
   Cycle44()  
   Cycle45()
   Cycle46()
   Cycle47()  
   Cycle48()  
   Cycle49()
   Cycle50() 
   Cycle51() 
   Cycle52() 
   Cycle53() 
   Cycle54() 
   Cycle55() 
   Cycle56() 
   Cycle57() 
   
   Cycle61()  
   Cycle62()  
   Cycle63()  
   Cycle64()  
   Cycle65()   
   Cycle66()  
   Cycle67()  
   Cycle68()  
   
   Sleep(50) 
   $z1 = $z1 + 1   
   
WEnd
Func _Exit()
    Exit
EndFunc


;ПАУЗА 

Func Cycle1() 
   $t1 = 1
   While $t1 <= 1
	    ;_______________________________________________
	     
		 Sleep(5000)
        Cycle8()		 
        ;_______________________________________________
   Sleep(50) 
   $t1 = $t1 + 1   
      ConsoleWrite('Cycle1 ' & $t1 & @LF)
   WEnd
EndFunc 


Func Cycle8() 
   $t8 = 1
   While $t8 <= 1
	    ;_______________________________________________
	     
		 MouseMove(124, 77, 5) 
		Sleep(1000)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(200)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(4000)
		MouseMove(594, 273, 5) 
		Sleep(1000)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(200)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		$i1 = 0
   While $i1 <= 16
	    MouseMove(683, 113, 5) 
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(200)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		MouseMove(848, 702, 5)
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(800)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		MouseMove(717, 129, 5)
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(200)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		MouseMove(848, 702, 5)
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(800)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		
		PixelSearch( 436, 346, 446, 358, 0xFFDA1E, 0, 1)
		If Not @error Then
		$i1 = 16
		$i1 = $i1 + 1
		Else	
			
	    $i1 = $i1 + 1
		EndIf
		WEnd
		
		Sleep(500)
		MouseMove(516, 451, 5) 
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(800)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		MouseMove(920, 59, 5) 
		Sleep(500)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(800)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(500)
		Sleep(50) ;+++ контроль
        Cycle9()		 
        ;_______________________________________________
   Sleep(50) 
   $t8 = $t8 + 1   
      ConsoleWrite('Cycle8 ' & $t8 & @LF)
   WEnd
EndFunc



Все написано в таком стиле, как в примере.

Заранее благодарю.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ошибка: превышен максмиальный уровень рекурсии
Избавляейтесь от неё и всё.
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
SyDr сказал(а):
Ошибка: превышен максмиальный уровень рекурсии
Избавляейтесь от неё и всё.


А как от неё можно избавиться, подскажите пожалуйста?А то просто при её выскакивании скрипт перестаёт работать, а при закрытии ошибки закрывается и сам скрипт, а я не всегда рядом с компьютером)
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Can
Судя по тому, что время работы скрипта каждый раз различно, значит количество уровней вложенности при выполнении скрипта каждый раз разное и непредсказуемо меняется...
Нужно постараться избавиться от вложенного вызова функций, то есть, когда функция F1 вызывает функцию F1 (себя) или функция F1 вызывает F2, а функция F2 вызывает F1... Количество вложенных уровней не может превышать 5100...
 

SyDr

Сидра
Сообщения
651
Репутация
158
Код:
Func First()
...
Next()
...
EndFunc

Func Next()
...
First()
EndFunc


Не надо вот так делать без особой необходимости.

Заменить можно циклом, который вызывает сначала одну функцию, потом другую.
К примеру, в основной программе вызывается функция First(), а в этой функции вызывается Next(), которая опять вызывает First() следует заменить на цикл, который сначала вызывает First(), а потом Next(). При этом сами функции друг на друга не ссылаются.
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
Спасибо за ответы, будем пробовать. Жаль что переделывать очень много, и ограничение конечно в 5100 :(


А можно небольшой примерчик на основе моего вложенного ниже маленького скрипта, а то что-то я не очень чётко понял:

Код:
HotKeySet ( "{ESC}" ,"_Exit")
Global $i,$p,$r

While 1 
   Cycle1()
   Cycle2()
   Cycle3()
   Sleep(270)
WEnd
Func _Exit()
    Exit
EndFunc

Func Cycle1() 
   $i = 1
   While $i <= 1
	    ;_______________________________________________
	    PixelSearch( 180, 578, 187, 584, 0x40404F, 0, 1) 
		 If Not @error Then 
		Sleep(100)
		Cycle2() 
	Else
		Cycle3() 
		EndIf
		;_______________________________________________
   Sleep(50) 
   $i = $i + 1   
      ConsoleWrite('Cycle1 ' & $i & @LF)
   WEnd
EndFunc 


Func Cycle2() 
   $p = 1
   While $p <= 1
	    ;_______________________________________________
	    
		Sleep(100)
		Cycle1() 
	
		;_______________________________________________
   Sleep(50) 
   $p = $p + 1   
      ConsoleWrite('Cycle2 ' & $p & @LF)
   WEnd
EndFunc 


Func Cycle3() 
   $r = 1
   While $r <= 1
	    ;_______________________________________________
	    
		Sleep(10000)
		Cycle1() 
	
		;_______________________________________________
   Sleep(50) 
   $r = $r + 1   
      ConsoleWrite('Cycle3 ' & $r & @LF)
   WEnd
EndFunc
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Can [?]
А можно небольшой примерчик на основе моего вложенного ниже маленького скрипта, а то что-то я не очень чётко понял:
[list type=decimal]
[*]Вызывается Cycle1()
[*]После PixelSearch() в Cycle1() вызываестя Cycle2() или Cycle3()
[*]Cycle2() или Cycle3() вызывают Cycle1()
[*]После PixelSearch() в Cycle1() вызываестя Cycle2() или Cycle3()
[*]Cycle2() или Cycle3() вызывают Cycle1()
[*]После PixelSearch() в Cycle1() вызываестя Cycle2() или Cycle3()
[*]Cycle2() или Cycle3() вызывают Cycle1()
[*]итд
[*]
[/list]
Возможное решение: в Cycle2() и Cycle3() пишем Return вместо вызова Cycle1()

А вообще пример не отформатирован имеет уйму не нужных конструкций, а так же в нём отсутствует функция _Exit().


Добавлено:
Сообщение автоматически объединено:

Это делало бы то же самое что и пример не вылетая при этом.
Код:
While 1
	PixelSearch(180, 578, 187, 584, 0x40404F, 0, 1)
	If @error Then
		Sleep(10000)
	Else
		Sleep(200)
	EndIf
WEnd
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
dwerf

Спасибо, но мой скрипт приведен, чтобы понять получше, где SyDr приводил пример, естественно у меня будет все гораздо сложнее :smile:
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Can
У меня просьба: ответь, пожалуйста:
1. какую задачу выполняет функция Cycle1()?
2. какую задачу выполняет функция Cycle2()?
3. какую задачу выполняет функция Cycle3()?
Крайне важно разделить их задачи...
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
snoitaleR сказал(а):
Can
У меня просьба: ответь, пожалуйста:
1. какую задачу выполняет функция Cycle1()?
2. какую задачу выполняет функция Cycle2()?
3. какую задачу выполняет функция Cycle3()?
Крайне важно разделить их задачи...

Да, в итоге будет где-то функций 40, которые будут при разных обстоятельствах выполнять разные задачи и переходить на указанные функции, и так бесконечно. Но в определенный момент, может небольшой сбой, они видимо ссылаются подряд на одну и туже функцию 5100 раз, и происходит ошибка, прога вылетает.

Смотри мой первый скрипт в самом верху, только там маленький кусочек приведен в пример.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Can [?]
А можно небольшой примерчик на основе моего вложенного ниже маленького скрипта, а то что-то я не очень чётко понял:
Нельзя. Настоятельно рекомендую в данном вопросе не искать сторонее решение, а разобраться.
Смотри:
Любая из функций у тебя никогда не выполняется до конца - вызывает другую функцию.
Программа:
1) Пошёл цикл
2) Вызвалась функция 1
3) Из неё обязательно будет вызвана функция 2 или 3
4) Из функции 2 или 3 обязательно вызывается функция 1. См. пункт 3

Таким образом, в коде много вещей, которые не будут вызваны ни при каких обстоятельствах.
Вот код, абсолютно идентичный тому, что вы привели в качестве примера:
Код:
HotKeySet("{ESC}", "_Exit")

Cycle1()

Func _Exit()
	Exit
EndFunc

Func Cycle1()
	;_______________________________________________
	PixelSearch(180, 578, 187, 584, 0x40404F, 0, 1)
	If Not @error Then
		Sleep(100)
		Cycle2()
	Else
		Cycle3()
	EndIf
EndFunc


Func Cycle2()
	Sleep(100)
	Cycle1()
EndFunc


Func Cycle3()
	Sleep(10000)
	Cycle1()
EndFunc


Хотя ладно, можно :smile: Пример без рекурсии для изменённого скрипта:
Код:
HotKeySet("{ESC}", "_Exit")

Global $nF = 1

While 1
	Switch $nF
		Case 1
			Cycle1()
		Case 2
			Cycle2()
		Case 3
			Cycle3()
	EndSwitch
WEnd

Func _Exit()
	Exit
EndFunc

Func Cycle1()
	;_______________________________________________
	PixelSearch(180, 578, 187, 584, 0x40404F, 0, 1)
	If Not @error Then
		Sleep(100)
		Return 2
	Else
		Return 3
	EndIf
EndFunc


Func Cycle2()
	Sleep(100)
	Return 1
EndFunc


Func Cycle3()
	Sleep(10000)
	Return 1
EndFunc
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
SyDr

Большое спасибо за второй пример без рекурсии, будем пробовать!
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
SyDr

Что то этот пример без рекурсии у меня не работает, не переходит с 1 цикла на второй ? :mad:

Код:
HotKeySet("{ESC}", "_Exit")

Global $nF = 1

While 1
    Switch $nF
        Case 1
            Cycle1()
        Case 2
            Cycle2()
        Case 3
            Cycle3()
    EndSwitch
WEnd

Func _Exit()
    Exit
EndFunc

Func Cycle1()
    ;_______________________________________________
     Sleep(500)
		
		Return 2
EndFunc


Func Cycle2()
    Sleep(100)
	MouseMove(65, 714, 5)
        Sleep(1000)
		MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(100)
        MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(30000)
		MouseMove(900, 490, 5)
		Sleep(1000)
		MouseDown("left")
        Sleep(50)
        MouseUp("left")
		Sleep(200)
		MouseDown("left")
        Sleep(50)
        MouseUp("left")
		Sleep(100)
		Sleep(4000)
		MouseMove(460, 460, 5)
		Sleep(1000)          ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(200)           ;+
		MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
		Sleep(9000)
    Return 3
EndFunc


Func Cycle3()
    Sleep(10000)
    Return 1
EndFunc



Подскажите, что не так?
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Can
Нужно возвращать переменную.
Код:
$nF = Int('N')
Return $nF
В вашем случае она глобальная, ей просто нужно присвоить значение:
Код:
HotKeySet("{ESC}", "_Exit")

Global $nF = 1

While 1
    Switch $nF
        Case 1
            Cycle1()
        Case 2
            Cycle2()
        Case 3
            Cycle3()
    EndSwitch
WEnd

Func _Exit()
    Exit
EndFunc

Func Cycle1()
	ConsoleWrite("Cycle1()" & @CRLF)
	Sleep(3000)
	$nF = 2  
EndFunc


Func Cycle2()
	ConsoleWrite("Cycle2()" & @CRLF)
	Sleep(3000)
	$nF = 3 
EndFunc


Func Cycle3()
	ConsoleWrite("Cycle3()" & @CRLF)
	Sleep(3000)
	$nF = 1
EndFunc
 

SyDr

Сидра
Сообщения
651
Репутация
158
Can [?]
Что то этот пример без рекурсии у меня не работает, не переходит с 1 цикла на второй ?
angry.gif

Я забыл одну вещь >_<
Можешь сделать, как в посте Garrett. А можешь так:
Код:
HotKeySet("{ESC}", "_Exit")

Global $nF = 1

While 1
    Switch $nF
        Case 1
            $nF = Cycle1()
        Case 2
            $nF = Cycle2()
        Case 3
            $nF = Cycle3()
    EndSwitch
WEnd

Func _Exit()
    Exit
EndFunc

Func Cycle1()
    ;_______________________________________________
     Sleep(500)
        
        Return 2
EndFunc


Func Cycle2()
    Sleep(100)
    MouseMove(65, 714, 5)
        Sleep(1000)
        MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(100)
        MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(30000)
        MouseMove(900, 490, 5)
        Sleep(1000)
        MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(200)
        MouseDown("left")
        Sleep(50)
        MouseUp("left")
        Sleep(100)
        Sleep(4000)
        MouseMove(460, 460, 5)
        Sleep(1000)          ;+
        MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
        Sleep(200)           ;+
        MouseDown("left")    ;+
        Sleep(50)            ;+
        MouseUp("left")      ;+
        Sleep(9000)
    Return 3
EndFunc


Func Cycle3()
    Sleep(10000)
    Return 1
EndFunc
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Can
Попробуйте работать по координатам клиентской части окна.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Can
IMHO у вас в коде много простых ошибок.
К примеру:
Код:
If ... Then
	;...
Else
	;...
Else
	;...
EndIf

IF("условие") выполняет операцию ИЛИ! То есть или 1 или 2 в зависимости от условия!
Если вам нужно проверять > 2x вариантов, есть инструкция ElseIF("условие")
Так же можно воспользоваться конструкциями Switch и Select
Посмотрите (яяяя донка 1005.au3)
Код:
Func Cycle42()
там как раз такая ошибка. Видимо поэтому скрипт и виснет. Он не поймет, что от него хотят.
 
Автор
C

Can

Новичок
Сообщения
59
Репутация
1
Вроде разобрался, Всем огромное спасибо за помощь!
 
Верх