【发布时间】:2016-12-06 20:06:22
【问题描述】:
在我的应用程序中,我有一个协程,它可能等待其他几个协程,并且每个如果这个协程,可能等待另一个协程,依此类推。 如果这样的协程之一失败,则无需执行所有其他尚未执行的协程。 (在我的情况下,这甚至是有害的,我想启动几个回滚协程来代替)。 那么,如何取消所有嵌套协程的执行呢?这是我现在所拥有的:
import asyncio
async def foo():
for i in range(5):
print('Foo', i)
await asyncio.sleep(0.5)
print('Foo2 done')
async def bar():
await asyncio.gather(bar1(), bar2())
async def bar1():
await asyncio.sleep(1)
raise Exception('Boom!')
async def bar2():
for i in range(5):
print('Bar2', i)
await asyncio.sleep(0.5)
print('Bar2 done')
async def baz():
for i in range(5):
print('Baz', i)
await asyncio.sleep(0.5)
async def main():
task_foo = asyncio.Task(foo())
task_bar = asyncio.Task(bar())
try:
await asyncio.gather(task_foo, task_bar)
except Exception:
print('One task failed. Canceling all')
task_foo.cancel()
task_bar.cancel()
print('Now we want baz')
await baz()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.close()
这显然行不通。如您所见,foo 协程如我所愿被取消,但bar2 仍在运行:
Foo 0
Bar2 0
Foo 1
Bar2 1
Foo 2
Bar2 2
One task failed. Canceling all
Now we want baz
Baz 0
Bar2 3
Baz 1
Bar2 4
Baz 2
Bar2 done
Baz 3
Baz 4
所以,我肯定做错了什么。这里的正确方法是什么?
【问题讨论】:
-
你可能会发现 RxPy 也很有帮助。在这里查看github.com/ReactiveX/RxPY
标签: python asynchronous async-await python-asyncio