我查看了akka scheduler和example here,它允许我安排定期和单个任务。我需要使用以下签名创建一个方法:
def doWhile(fn: => Unit, whileFn: => Boolean, period:Long) = {
// while whileFn evaluates to true, repeat fn every period millisecs
}
我可以将fn
包含在评估fnNew
的另一个方法whileFn
中,如果为true则执行fn
。然后我可以安排fnNew
定期执行。但这似乎是一个糟糕的黑客。在fnNew
评估为假的那一刻,我希望whileFn
“未计划”。什么是正确的方法?
编辑:我想避免使用显式actor,并希望避免使用共享状态,如下面的代码所示:
def doRegularly(fn: => Unit, periodMillis:Long) =
scheduler.schedule(0 seconds, periodMillis milliseconds)(fn)
def doWhile(fn: => Unit, whileFn: => Boolean, period:Long) = {
var c:Option[Cancellable] = None
c = Some(doRegularly(
if (whileFn) fn
else {
if (c.isDefined) c.get.cancel
}, period))
}
(具有共享值c
)
答案 0 :(得分:2)
我认为你可以利用scheduleOnce
来完成你想要的,而不是在doWhile
的定义中拥有共享状态。如果你这样定义doWhile
:
def doWhile(fn: => Unit, whileFn: => Boolean, duration:FiniteDuration)(implicit sys:ActorSystem) {
if (whileFn){
fn
sys.scheduler.scheduleOnce(duration)(doWhile(fn, whileFn, duration))(sys.dispatcher)
}
}
然后,您可以使用以下代码调用它:
implicit val system = ActorSystem("SchedTest")
var count = 1
doWhile(printAndInc, count <= 10, 1 second)
def printAndInc{
println(s"count is $count")
count += 1
}
如果你运行上面的代码,你会看到它打印数字1到10,并在第二次暂停之间。
答案 1 :(得分:1)
从docs,您可以使用cancel
//This will schedule to send the Tick-message
//to the tickActor after 0ms repeating every 50ms
val cancellable =
system.scheduler.schedule(0 milliseconds,
50 milliseconds,
tickActor,
Tick)
//This cancels further Ticks to be sent
cancellable.cancel()
schedule
方法返回类型为Cancellable
的对象,该对象具有cancel方法。
我不确定,您打算如何使用whileFn
,但只要它返回false,就在Cancellable
对象上调用cancel方法。