我正在尝试使用延迟来向可能正在等待它的多个协程发出任务结束的信号。我想要threading.Event
中事件的相同行为。协程等待,但是只有一个得到延迟解雇的结果。代码示例:
from twisted.internet import defer, task, reactor
async def test(d):
print("Awaiting")
print(f"Await finished: {await d}")
d = defer.Deferred()
defer.ensureDeferred(test(d))
defer.ensureDeferred(test(d))
task.deferLater(reactor, 1, d.callback, 'Deferred Fired')
reactor.run()
输出:
Awaiting
Awaiting
Await finished: Deferred Fired
Await finished: None
我期待中:
Awaiting
Awaiting
Await finished: Deferred Fired
Await finished: Deferred Fired
但是当一个协程等待两次或更多次时,它会很好地工作:
async def test(d):
print("Awaiting")
print(f"Await finished: {await d}")
print(f"Await finished: {await d}")
d = defer.Deferred()
defer.ensureDeferred(test(d))
task.deferLater(reactor, 1, d.callback, 'Deferred Fired')
您正在尝试使用延期作为同步的方法,但这并不是它的预期目的,至少不是靠它们自己。我假设您想像使用Deferred
一样使用Event.wait()
?这是我通常看到的范例:
Event.wait()
[这里,我们有一个函数返回延迟/将来(即from dataclasses import dataclass, field
from typing import List
from twisted.internet import defer, reactor
@dataclass
class Thing:
deferred_list: List[defer.Deferred] = field(default_factory=list)
def notifyFinished(self) -> defer.Deferred:
deferred = defer.Deferred()
self.deferred_list.append(deferred)
return deferred
def finish(self):
for index, deferred in enumerate(self.deferred_list):
deferred.callback(index + 1)
self.deferred_list = []
async def doSomethingElse(d):
print("[!] awaiting...")
print(f"[x] done waiting: {await d}")
def main():
thing = Thing()
for _ in range(5):
d = thing.notifyFinished()
defer.ensureDeferred(doSomethingElse(d))
reactor.callLater(5, thing.finish)
reactor.run()
main()
),跟踪那些延迟/将来的函数,一旦作业完成,就调用一个信号通知任务结束的函数(即notifyFinished
)。 finish
仅打算触发一次(Deferred
也可能触发,但请不要在其上引用我),因此使用此方法可确保返回单个Future
对象并同时触发。