儘管可能無法中斷線程,但可以通過cancel
函數來停止延遲,我認爲該函數可用於Twisted 10.1.0和更高版本。
我已經使用了下面的類來使Deferreds回調一個特定的函數,如果Deferred在一段時間後還沒有被觸發。對於與OP中主題相同的問題可能會有用。
編輯:正如下面的評論建議,最好不要從defer.Deferred
繼承。因此,我更改了代碼以使用實現相同效果的包裝器。超時前
class DeferredWrapperWithTimeout(object):
'''
Holds a deferred that allows a specified function to be called-back
if the deferred does not fire before some specified timeout.
'''
def __init__(self, canceller=None):
self._def = defer.Deferred(canceller)
def _finish(self, r, t):
'''
Function to be called (internally) after the Deferred
has fired, in order to cancel the timeout.
'''
if ((t!=None) and (t.active())):
t.cancel()
return r
def getDeferred(self):
return self._def
def addTimeoutCallback(self, reactr, timeout,
callUponTimeout, *args, **kw):
'''
The function 'callUponTimeout' (with optional args or keywords)
will be called after 'timeout' seconds, unless the Deferred fires.
'''
def timeoutCallback():
self._def.cancel()
callUponTimeout(*args, **kw)
toc = reactr.callLater(timeout, timeoutCallback)
return self._def.addCallback(self._finish, toc)
例回調:
from twisted.internet import reactor
from DeferredWithTimeout import *
dw = DeferredWrapperWithTimeout()
d = dw.getDeferred()
def testCallback(x=None):
print "called"
def testTimeout(x=None):
print "timedout"
d.addCallback(testCallback)
dw.addTimeoutCallback(reactor, 20, testTimeout, "to")
reactor.callLater(2, d.callback, "cb")
reactor.run()
打印 「叫」,別無其他。回調之前
例超時:
from twisted.internet import reactor
from DeferredWithTimeout import *
dw = DeferredWrapperWithTimeout()
d = dw.getDeferred()
def testCallback(x=None):
print "called"
def testTimeout(x=None):
print "timedout"
d.addCallback(testCallback)
dw.addTimeoutCallback(reactor, 20, testTimeout, "to")
reactor.run()
打印 「已逾時」 20秒後,並沒有別的。
你真的不應該繼承'延遲'。實現這個功能作爲一個單獨的幫手,而不是一個子類。 http://pyvideo.org/video/1684/the-end-of-object-inheritance-the-beginning-of – 2013-09-26 11:33:21
除了關於不繼承事物的常見警告之外,「延遲」是一個*特別*壞事子類,因爲它的行爲假定它自己的實現非常具體,並且不會很好地反應某些方法被覆蓋。 – Glyph 2013-09-26 19:15:02
感謝您觀看該視頻的鏈接!它完全改變了我設計代碼的方式。 – Corey 2015-04-18 00:43:32