在tcl中介入"after"的一种方法

3

我写了一个tcl脚本,其中有20秒的等待时间。有时候我需要在等待过程中退出(或者说停止)等待。我使用了:after 20000

有办法停止等待吗?

2个回答

3
如果你只是使用以下代码:
after 20000

如果不想使用Ctrl+Ckill来结束进程,那么没有其他方法。

如果您想在Tcl中进行可中断的等待,请使用以下代码:

after 20000 set done 1
vwait done

这将继续服务事件,因此可以被中断。保存由after 20000 set done 1返回的令牌,您可以取消计时器(例如,如果您想重新安排它)。否则,自己设置(全局done)变量,您将更快完成等待。


大多数Tcl程序员实际上并不经常使用“after 20000”,因为它除了等待之外什么也不做... - Donal Fellows

2
在我之前的一项工作中,我曾经处理过类似情况的脚本。当我的脚本等待 N 秒后,除非用户按下 Ctrl+C,否则它会继续执行。以下是我的脚本,只保留了最基本的部分以展示其工作原理。
package require Tclx

proc abortTest {} {
    after cancel $::afterId
    set ::status "Ctrl+C detected"
}

#
# Main
#

puts "start"
set status "Ctrl+C not detected"

# when Ctrl+c detected, call abortTest
signal trap SIGINT abortTest

# Wait for N seconds
set WAIT_TIME 10000
set afterId [after $WAIT_TIME {set status "Exit normally"}]
puts "Wait for [expr {$WAIT_TIME / 1000}] seconds"
vwait status; # wait until status changed

puts $status
puts "end"

讨论

  • signal命令表示:“如果用户按下Ctrl+C,则调用abortTest
  • 需要注意的是,在这种形式下,after命令会立即退出,但是TCL解释器会在10秒后执行set status ...命令。
  • vwait命令会等待变量status的值发生改变。
  • 如果在10秒内用户没有按下Ctrl+C,那么变量status将被设置为"正常退出",此时vwait命令将退出。
  • 如果在此期间用户按下了Ctrl+C,则status将被更改,vwait命令将退出。

更新

在缩小原始脚本的同时,我删除了取消after命令的部分。现在我正在将其放回。需要注意的是,after命令返回一个ID,我在abortTest中使用它来取消操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接