防止 current thread (当前线程)被其他线程中断。
Critical [, Off]
Critical 50 ; 请看底部的注释 bottom of remarks.
如果第一个参数被省略(或者是 On),则 current thread (当前的线程)被设置为 Critical (关键线程)这就意味着他不会被其他的线程所中断。如果第一个参数是Off(或者0,在 1.0.48+ 版本中),则当前的线程忽略 "Thread Interrupt" 的设置,立即被设置为可以中断的状态。
不同于 high-priority (高优先级线程),如果在Critical 状态的线程运行中产生了另一个事件,则该事件不会被忽略。例如,当用户按下一个热键 hotkey, 但该热键的线程正以 Critical 状态运行,这时用户按下的热键会被缓冲,直到当前的线程结束或者被设置为可以中断的非关键状 态,这时用户按下的热键才会被一个新的线程所执行。
一个处于 Critical 状态的线程也会被紧急事件所中断。紧急事件包括:1) OnExit 子 程序;2)任意一个监听的消息值小于0x312的 OnMessage() 函数(或是被这些消息所触发的 callback 函数);3)任意一个被当前线程自己所间接触发的 (通过 SendMessage 或 DllCall 等函数所触发) 为了避免被这些函数的中断,可以临时的关闭这些函数。
当缓冲事件等待被线程执行时,使用"Critical Off"不能够立即中断当前的线程。相反,执行中断平均需要花费5毫秒。这样在中断前,至少在"Critical Off"下面的一行代码 99.999%可能会被执行。你可以通过利用 Sleep -1 或用 WinWait 等待一个不存在的窗口等方法,进行强制中断。
当一个 MsgBox 或者其他对话框显示时,会中断一个Critical状态的线程,而不同于 "Thread Interrupt",线程会在对话框关闭时恢复Critical 状态。
关于如何保存和还原当前 Critical 的设置,请参考 A_IsCritical 。因为 Critical 状态是一个特殊设置的线程,当线程结束,接下来运行的线程或者重新运行的线程(如果有的话)不会再以Critical 状态运行。所以不需要在结束一个线程后再声明"Critical Off"。
如果在自动运行片段(也就是脚本的最上面的一段代码)没有声明 Critical ,所有的线程不会以 Critical 状态运行(尽管可以设置 "Thread Interrupt" 来实现)。相反,如果在自动运行片段声明了Critical 且不曾关闭Critical状态,则每个新运行的线程(如 hotkey,custom menu item (自定义菜单项)和 timed 子程序)都会以 Critical 状态运行。
"Thread NoTimers" 命令和 Critical 相似,除了他可以防止被 timers 所中断。
在v1.0.47 及其以后的版本中,设置 Critical 状态同时会对 current thread (当前线程 )产生 SetBatchLines -1 效果。
在v1.0.47及其以后的版本中,第一参数 指定为一个正数(例如Critical 30 ),表示该线程为关键线程,但是也改变了检查 内部消息队列的间隔时间。如果第一个参数为On,会以默认16毫秒间隔检查,当参数为Off则以5毫秒间隔检查。增加推迟消息/事件的延时间隔,可 以给 current thread (当前线程 )更多的时间来结束。这样可以减少因为“线程正在运行”而导致消息 OnMessage() 和 界面事件 GUI events 丢失的可能性。然而,例如 Sleep 和 WinWait 命令会默认检查消息而忽略这个设置(一个解决方案是 DllCall("Sleep", Uint, 500))。注意:检 查消息的时间间隔增加的太多有可能减少各种事件的响应,如 GUI 窗口的重绘。
Thread (command), Threads , #MaxThreadsPerHotkey, #MaxThreadsBuffer, OnMessage(), RegisterCallback(), Hotkey, Menu, SetTimer
#space:: ; Win+Space hotkey.
Critical
ToolTip 在这个提示消失之前不会再有新的线程运行
Sleep 3000
ToolTip ; 关闭提示
return ; 热键子程序结束,以下的线程不会再以关键状态运行。