Что нового

Как принудительно выйти из функции, если она зависла? Код внутри

Suppir

Продвинутый
Сообщения
967
Репутация
62
Код:
Main()

Func Main()
	Compare()
	PrintResult()
EndFunc

Func Compare()
	ProgressOn("Моя программа", "Делаем расчет", "...", -1, -1, 2)
	while 1
;~ 		представим, что функция Compare зависла
		Sleep (100)
	wend
EndFunc

Func PrintResult()
	ConsoleWrite ("Все нормально" & @CRLF)
EndFunc



Как сделать следующую вещь:

Пользователь видит, что функция Compare зависла.
Он нажимает на иконку скрипта в трее - и эта зависшая функция должна завершить свою работу.
При этом функция main() должна продолжать выполняться. Можно ли реализовать с помощью AdlibRegister() ?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если это не предусмотреть в самой функции Compare(), то никак (ну, или выносить Compare() в отдельный процесс).
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Suppir
Попробуйте так:
Код:
#include <Constants.au3>

Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 1)

$fGo = False
$i = 0
HotKeySet('+{Esc}', '_Go');Shift+Esc
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, '_Go')
Main()

Func Main()
	Compare()
	PrintResult()
	Sleep(1000)
	Compare()
	PrintResult()
EndFunc   ;==>Main

Func Compare()
	ProgressOn("Моя программа", "Делаем расчет", "...", -1, -1, 2)
	While 1
		$i += 1
		If $i = 50 Then $i = 0
		ProgressSet($i, $i & " percent")
		If $fGo Then
			ProgressOff()
			$fGo = False
			$i = 0
			Return
		EndIf
;~      представим, что функция Compare зависла
		Sleep(100)
	WEnd

EndFunc   ;==>Compare

Func PrintResult()
	ConsoleWrite("Все нормально" & @CRLF)
EndFunc   ;==>PrintResult
Func _Go()
	$fGo = True
EndFunc   ;==>_Go
Только не знаю, будет ли это работать при настоящем зависании.
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
madmasles

Довольно интересный подход. А я не знал, что хоткей будет работать во время исполнения функции. Тем более, что по хоткею вызывается другая функция.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Suppir [?]
А я не знал, что хоткей будет работать во время исполнения функции
И, если кликнуть левой кнопкой мышки по иконке скрипта в системной панели(Tray), то тоже будет работать.
Но, повторяю, не знаю, будет ли это работать при настоящем зависании.

Цикл можно поменять на
Код:
Do
;...
Until $fGo
ProgressOff()
$fGo = False
$i = 0
;или
While Not $fGo
;...
WEnd
ProgressOff()
$fGo = False
$i = 0
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Ребята, у меня функция не зависает в прямом смысле этого слова. Просто у пользователя может быть слабая машина и функция будет работать слишком долго. Необходим способ прерывания этой функции по желанию пользователя. Функция представляет собой 10000 итераций, причем каждая итерация выполняется быстро. Делать каждую итерацию проверки нажатия - слишком ресурсозатратно. Поэтому нужен какой-то способ делать проверку нажатия раз в 3 - 5 секунд (за это время успевает проскочить 1000 итераций функции). Если пользователь нажал отмену, то прервать функцию. В общем, нужно еще подумать...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Suppir [?]
Необходим способ прерывания этой функции по желанию пользователя. Функция представляет собой 10000 итераций, причем каждая итерация выполняется быстро.
Код:
#include <Constants.au3>

Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 1)

$fGo = False

HotKeySet('+{Esc}', '_Go');Shift+Esc
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, '_Go')
For $i = 1 To 5
	$sText = Main()
	MsgBox(64, 'Test № ' & $i, $sText)
Next

Func Main()
	Local $sTest = Compare()
	Return $sTest
EndFunc   ;==>Main

Func Compare()
	Local $sResult = '00000x00000'
	For $i = 0 To 10000
		If $fGo Then
			$fGo = False
			ToolTip('')
			Return $sResult
		EndIf
		For $j = 0 To 10000
			If $fGo Then
				$fGo = False
				ToolTip('')
				Return $sResult
			EndIf
			$sResult = StringFormat('%05d', $i) & 'x' & StringFormat('%05d', $j)
			ToolTip($sResult, 0, 0)
			Sleep(50)
		Next
		Sleep(50)
	Next
	Return $sResult
EndFunc   ;==>Compare

Func _Go()
	$fGo = True
EndFunc   ;==>_Go
 
Верх