Critical

AutoHotKey

Critical

防止当前线程被其他线程中断, 或开启可中断.

Critical [, Off]
Critical 50 ; 请参阅备注底部.

如果首个参数省略 (或为单词 On), 则设置 当前线程 为关键的, 这意味着它不会被其他线程中断. 如果首个参数为 Off(或在 v1.0.48+ 为数字 0),则当前线程会不论 Thread Interrupt 如何设置都会变成可中断状态.

关键线程的行为

高优先级 线程不同, 在关键线程中产生的事件不会被丢弃. 例如, 在当前线程为关键线程时用户按下了 热键, 那么此热键会被缓冲到当前线程结束或成为非关键线程时才作为新的线程启动.

关键线程也会被紧急事件中断. 紧急事件包括: 1) OnExit 子程序; 2) 监听消息号小于 0x312 的任何 OnMessage() 函数 (或被这些消息触发的 回调); 和 3) 由紧急线程自身间接触发的任何 回调 (例如通过 SendMessageDllCall). 要避免被这些事件中断, 可以临时禁用这些函数.

关键线程在显示 MsgBox 或其他对话框时, 会变成可中断的. 但是,与 Thread Interrupt 不同,在用户解除对话框后这个线程会再恢复为关键的.

Critical Off

当缓冲的事件等待启动新的线程时, 使用 Critical Off 不会导致立即中断当前线程, 而会经过平均5ms才发生中断. 这会导致在中断前有超过 99.999% 的可能执行了至少一行 Critical Off 后面的代码. 可通过使用像 Sleep -1WinWait 一个尚不存在的窗口这样的延迟手段立即产生强制中断.

Critical Off 会取消当前线程的不可中断性周期即使该线程是非关键线程, 因此会让像 GuiSize 这样的事件马上或不出意外的被处理.

线程设定

如何保存和还原当前线程的关键设定请看 A_IsCritical . Critical 是一个对于特定线程的设定, 当一个关键线程结束时,随后/接续的线程(如果有的话)会自动变成非关键线程. 因此没有必要在一个线程结束时马上使用 "Critical Off" .

如果在自动执行段没有使用 Critical (脚本开头部分), 所有的线程将会以非关键线程开始(但 线程中断 的设定仍然有效). 与之对比的是,如果自动执行段打开了 Critical 但随后并没有关闭过它, 每个新启动的 线程 (像 热键, 自定义菜单项目, 或 定时 子程序) 都会以关键线程开始.

Thread NoTimers 命令类似于 Critical ,但前者仅保护线程不被 定时器 中断.

在 v1.0.47+,打开 Critical 的同时也会让 SetBatchLines -1当前线程生效.

消息检查间隔

在 v1.0.47+的版本, 指定一个正数作为首个参数 (如 Critical 30) 将会打开 Critical 但同时也会改变检查内部消息队列的时间间隔(以ms毫秒计). 如果未指定该参数, 在Critical打开的状态下每16ms检查一次消息队列,在Critical关闭状态下每5ms检查一次. 延长时间间隔会推迟消息/事件的到达, 给出更多的时间让 当前线程 结束. 这会减少某些 OnMessage()GUI 事件 因为 "线程已运行" 而丢失的可能性. 然而, 像 SleepWinWait 这样的等待型命令则无视此设定而照常检查消息 (一个变通的解决办法是 DllCall("Sleep", Uint, 500)). 注意: 将消息检查间隔设置的太大会减少对多种事件的响应能力,例如 GUI 窗口的重绘.

相关

Thread(命令), 线程, #MaxThreadsPerHotkey, #MaxThreadsBuffer, OnMessage(), RegisterCallback(), Hotkey, Menu, SetTimer

示例

#space::  ; Win+Space 热键.
Critical
ToolTip No new threads will launch until after this ToolTip disappears.
Sleep 3000
ToolTip  ; 关闭提示.
return  ; 从热键子程序中返回, 结束当前线程. 随后的线程会按设置恢复为非关键的.