SetTimer 是 AHK 里非常常用的命令:自动保存、窗口监控、状态刷新、轮询接口、定时提醒,都离不开它。但很多脚本卡死、重复触发、CPU 占用高,也和定时器写法有关。

这篇文章重点讲四件事:定时器是否会重入、触发是否会排队、怎么关闭定时器,以及怎样动态修改间隔。理解这些后,你写出来的脚本会稳很多。

一、最基础的 SetTimer

#Requires AutoHotkey v1.1
#NoEnv
#SingleInstance Force

SetTimer, ShowTime, 1000
return

ShowTime:
FormatTime, now,, HH:mm:ss
ToolTip, %now%
return

这段代码每 1000 毫秒执行一次 ShowTime 标签。注意:SetTimer 后面接的是标签名,不是函数调用。标签最后通常要写 return,否则流程可能继续往下跑。

二、定时器会不会重入

定时器触发时,如果上一次执行还没结束,新触发通常不会同时再进入同一个线程执行。AHK 的线程模型会尽量避免同一段标签代码无限重入。但这不等于你可以放心写耗时任务,因为定时器触发可能被延迟,脚本响应也会变慢。

SetTimer, SlowJob, 500
return

SlowJob:
ToolTip, 开始处理
Sleep, 2000
ToolTip, 处理完成
return

上面这个例子里,定时器间隔是 500 毫秒,但任务本身要 2 秒。实际效果不会是每 500 毫秒稳定完成一次,而是脚本一直忙于处理这个标签。写定时器时,任务耗时最好明显小于定时间隔。

三、防止重复进入:加运行标记

如果定时器任务可能耗时,建议加一个运行标记。这样即使定时器再次触发,也会发现上一次还没结束,然后直接跳过。

isChecking := false
SetTimer, CheckWindow, 500
return

CheckWindow:
if (isChecking)
    return
isChecking := true

; 这里写可能耗时的检查逻辑
Sleep, 1200

isChecking := false
return

这个写法很适合窗口监控、网络轮询、找图找色、文件扫描等场景。它牺牲一点触发次数,但换来稳定性。

四、关闭和重新开启定时器

F1::
SetTimer, CheckWindow, 1000
ToolTip, 定时器已开启
return

F2::
SetTimer, CheckWindow, Off
ToolTip, 定时器已关闭
return

CheckWindow:
ToolTip, 正在检查窗口
return

Off 是关闭定时器,之后不会再触发;如果再次用数字间隔设置同一个标签,定时器就会重新开启。

五、动态修改间隔

同一个定时器可以反复设置不同间隔。比如普通状态下 1000 毫秒检查一次,忙碌状态下降低频率到 5000 毫秒。

fastMode := true
SetTimer, Watch, 1000
return

F3::
fastMode := !fastMode
interval := fastMode ? 1000 : 5000
SetTimer, Watch, %interval%
ToolTip, % "当前间隔:" interval "ms"
return

Watch:
; 定时任务
return

六、一次性定时器

AHK v1 里可以用负数间隔实现一次性定时器:触发一次后自动关闭。

SetTimer, HideTip, -1500
ToolTip, 这个提示 1.5 秒后消失
return

HideTip:
ToolTip
return

七、建议

  • 定时器任务要短,不要把长循环塞进定时器。
  • 可能耗时的任务加运行标记,防止重复进入。
  • 需要暂停时用 Off,不要靠全局变量空转。
  • 需要临时延迟执行时,用负数间隔的一次性定时器。
  • 多个定时器共存时,给标签起清楚的名字。

SetTimer 的关键不是“每隔多久执行一次”,而是“脚本忙的时候如何不乱”。把重入、关闭和间隔调整处理好,定时器就会成为很稳的工具。

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。