黑色袜子 发表于 2014-6-13 22:13:29

如何防止函数在循环导致界面假死【附例子】

本帖最后由 黑色袜子 于 2014-6-13 22:15 编辑

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
$Label11 = GUICtrlCreateLabel("tttt", 275, 125, 200, 21)
;GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetCursor(-1, 0)
GUICtrlSetOnEvent(-1, "_test1")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
        Sleep(1)
WEnd


func _test1()
_test2()
endfunc

func _test2()
sleep(99999)
;这时程序会卡在这个函数。不会响应任何事件。有时候还会导致界面假死!
;如果不先点击“ttt”是可以关闭界面的。但点击了“ttt”函数循环在这里。
endfunc

Func _quit()
        Exit
EndFunc
不知道这样表达各位能否明白。原谅我吧。我语文体育老师教的

afan 发表于 2014-6-13 22:13:30

该话题讨论较多。方法很多,具体按需求确定思路Opt('GUIOnEventMode', 1)
GUICreate('', 615, 438, 192, 124)
GUISetOnEvent(-3, '_quit')
$Label11 = GUICtrlCreateLabel('test', 275, 125, 200, 21)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetCursor(-1, 0)
GUICtrlSetOnEvent(-1, '_test1')
$iBtn = GUICtrlCreateButton('中止并退出', 275, 50, 100, 21)
GUICtrlSetOnEvent(-1, '_quit')
GUISetState(@SW_SHOW)
GUIRegisterMsg(0x111, '_WM_COMMAND')

While 1
        Sleep(100)
WEnd

Func _test1()
        _test2()
EndFunc   ;==>_test1

Func _test2()
        GUICtrlSetData($Label11, '死循环中…')
        Sleep(99999)
EndFunc   ;==>_test2

Func _quit()
        Exit
EndFunc   ;==>_quit

Func _WM_COMMAND($hWnd, $msg, $wParam, $lParam)
        If BitAND($wParam, 0xFFFF) = $iBtn Then _quit()
EndFunc   ;==>_WM_COMMAND

fspws 发表于 2014-6-13 23:10:47

这个问题 我也勾结过,毕竟au3不支持多线程,他必须等等执行完 sleep(99999) 。

qsy666888 发表于 2014-6-13 23:50:07

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
$Label11 = GUICtrlCreateLabel("tttt", 275, 125, 200, 21)
;GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetCursor(-1, 0)
GUICtrlSetOnEvent(-1, "_test1")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
      Sleep(1)
WEnd


func _test1()
_test2()
endfunc

func _test2()
sleep(250)
;这时程序会卡在这个函数。不会响应任何事件。有时候还会导致界面假死!
;如果不先点击“ttt”是可以关闭界面的。但点击了“ttt”函数循环在这里。
endfunc

Func _quit()
      Exit
EndFunc

黑色袜子 发表于 2014-6-14 00:48:11

回复 3# qsy666888


    我只是举例放个9999而已。如果放一些要处理比较久的代码。比如读取一些大文件,想网络发送数据。就卡在那里了

qsy666888 发表于 2014-6-14 07:28:12

回复 4# 黑色袜子


    au3貌似不能执行多线程,等待高手出现

黑色袜子 发表于 2014-6-14 12:33:16

本帖最后由 黑色袜子 于 2014-6-14 13:40 编辑

回复 6# afan


    这个是解决了这个问题。

如果有好多控件呢,每个都这样写吗?又或者代码执行到_test2()函数时造成界面假死怎么破?

不管怎样还是先谢谢,又学了一招

veket_linux 发表于 2014-6-14 17:25:57

au3 可以 调用 dll 就可以玩 多线程 ,先去找人写个线程的dll 给你调调吧(吧你要做的繁重任务仍给高人到dll里写的线程中去处理啦)

veket_linux 发表于 2014-6-14 17:26:04

au3 可以 调用 dll 就可以玩 多线程 ,先去找人写个线程的dll 给你调调吧(吧你要做的繁重任务仍给高人到dll里写的线程中去处理啦)

黑色袜子 发表于 2014-6-14 18:18:27

回复 9# veket_linux


    我曾经叫人帮我写过一个。但是不会用。

veket_linux 发表于 2014-6-14 18:30:06

滚动条往上拉 红色 字体的

风行者 发表于 2014-6-14 20:12:47

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
Opt("GUIOnEventMode", 1)
$Form1 = GUICreate("Form1", 615, 438, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "_quit")
$Label11 = GUICtrlCreateLabel("tttt", 275, 125, 200, 21)
;GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetColor(-1, 0x0000FF)
GUICtrlSetCursor(-1, 0)
GUICtrlSetOnEvent(-1, "_test1")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; Global Const $SC_CLOSE = 0xF060 ; 常量 WM_SYSCOMMAND
GUIRegisterMsg(0x0112, "WM_SYSCOMMAND")

While 1
        Sleep(1)
WEnd


Func _test1()
        _test2()
EndFunc   ;==>_test1

Func _test2()
        Sleep(99999)
        ;这时程序会卡在这个函数。不会响应任何事件。有时候还会导致界面假死!
        ;如果不先点击“ttt”是可以关闭界面的。但点击了“ttt”函数循环在这里。
EndFunc   ;==>_test2

Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
        If BitAND($wParam, 0xFFFF) = 0xF060 Then Exit
EndFunc   ;==>WM_SYSCOMMAND

Func _quit()
        Exit
EndFunc   ;==>_quit

baduxiyang 发表于 2014-6-18 17:13:37

sleep..这时间太长了吧。
页: [1]
查看完整版本: 如何防止函数在循环导致界面假死【附例子】