调度未来任务¶
假设我们希望在 X 秒后运行任务。实现此功能的方法在 reactor 接口 twisted.internet.interfaces.IReactorTime
中定义。
from twisted.internet import reactor
def f(s):
print("this will run 3.5 seconds after it was scheduled: %s" % s)
reactor.callLater(3.5, f, "hello, world")
# f() will only be called if the event loop is started.
reactor.run()
如果函数的结果很重要,或者需要处理它可能引发的异常,那么 twisted.internet.task.deferLater()
实用程序可以方便地创建 Deferred
并设置延迟调用。
from twisted.internet import task
from twisted.internet import reactor
def f(s):
return "This will run 3.5 seconds after it was scheduled: %s" % s
d = task.deferLater(reactor, 3.5, f, "hello, world")
def called(result):
print(result)
d.addCallback(called)
# f() will only be called if the event loop is started.
reactor.run()
如果我们希望任务每隔 X 秒重复运行一次,可以使用 twisted.internet.task.LoopingCall
。
from twisted.internet import task
from twisted.internet import reactor
loopTimes = 3
failInTheEnd = False
_loopCounter = 0
def runEverySecond():
"""
Called at ever loop interval.
"""
global _loopCounter
if _loopCounter < loopTimes:
_loopCounter += 1
print('A new second has passed.')
return
if failInTheEnd:
raise Exception('Failure during loop execution.')
# We looped enough times.
loop.stop()
return
def cbLoopDone(result):
"""
Called when loop was stopped with success.
"""
print("Loop done.")
reactor.stop()
def ebLoopFailed(failure):
"""
Called when loop execution failed.
"""
print(failure.getBriefTraceback())
reactor.stop()
loop = task.LoopingCall(runEverySecond)
# Start looping every 1 second.
loopDeferred = loop.start(1.0)
# Add callbacks for stop and failure.
loopDeferred.addCallback(cbLoopDone)
loopDeferred.addErrback(ebLoopFailed)
reactor.run()
如果我们希望取消已调度的任务
from twisted.internet import reactor
def f():
print("I'll never run.")
callID = reactor.callLater(5, f)
callID.cancel()
reactor.run()
与所有基于 reactor 的代码一样,为了使调度正常工作,必须使用 reactor.run()
启动 reactor。