如何在一定时间后调用回调函数

时间:2016-09-23 21:20:19

标签: python twisted

我正在使用Twisted和Txmongo lib。 在以下函数中,我想在5秒后调用cancelTest()。但代码不起作用。我怎样才能使它发挥作用?

from twisted.internet import task

def diverge(self, d):
    if d == 'Wait':
        self.flag = 1
        # self.timeInit = time.time()
        clock = task.Clock()
        for ip in self.ips:
            if self.factory.dictQueue.get(ip) is not None:
                self.factory.dictQueue[ip].append(self)
            else:
                self.factory.dictQueue[ip] = deque([self])
                # self.factory.dictQueue[ip].append(self)

        log.msg("-----------------the queue after wait")
        log.msg(self.factory.dictQueue)
###############################HERE, this does not work
        self.dtime = task.deferLater(clock, 5, self.printData)
#############################
        self.dtime.addCallback(self.cancelTest)
        self.dtime.addErrback(log.err)
    else:
        self.cancelTimeOut()
        d.addCallback(self.dispatch)
        d.addErrback(log.err)



def sendBackIP(self):
    self.ips.pop(0)
    log.msg("the IPs: %s" % self.ips)

    d = self.factory.service.checkResource(self.ips)

    d.addCallback(self.diverge) ###invoke above function
    log.msg("the result from checkResource: ")
    log.msg()

2 个答案:

答案 0 :(得分:0)

通常reactor.callLater()是你想要的功能。因此,如果需要在5秒后调用该函数,则代码将如下所示:

from twisted.internet import reactor
reactor.callLater(5, cancelTest)

奇怪的是,您的task.deferLater实施也应该有效。但是,如果没有看到更多的代码,我认为除了声明它很奇怪之外,我认为我不能帮助你更多:)

参考

答案 1 :(得分:0)

你几乎做的一切都是正确的;你没有正确地获得时钟部分。

twisted.internet.task.Clock 是IReactorTime的确定性实现,主要用于单元/集成测试,以获取代码中的确定性输出;你不应该在生产中使用它。

那么,你应该在生产中使用什么?的反应器!实际上,所有生产反应器实现都实现了IReactorTime接口。

只需使用以下导入和函数调用:

from twisted.internet import reactor
# (omissis)
self.dtime = task.deferLater(reactor, 5, self.printData)

只是一些旁注:

在你的文本片段上面的

中,你说要在五秒后调用cancelTest,但在代码中你实际调用了printData;当然,如果printData只是打印一些东西,不会提升并返回一个立即值,这将导致cancelTest函数被立即执行,因为它是一个链式的callcack; 但是如果你想真正100%确定,你应该在deferLater中调用cancelTest,而不是printData

另外,我不明白这是否是一种"超时&#34 ;;请注意,即使测试时间少于五秒,也会在所有情况下触发此类回调。如果您需要可取消的任务,则应直接使用reactor.callLater;这不会返回您可以使用的延期,但会让您取消预定的通话。