documentation for asyncio.gather说
但是,从一个简单的测试来看,如果在return_exceptions为False
时,如果其中一个任务引发了异常,则所有其他awaitable都将被取消(或更确切地说,如果我对术语不了解,则其他awaitable不会完成他们的工作):
import asyncio
async def factorial(name, number, raise_exception=False):
# If raise_exception is True, will raise an exception when
# the loop counter > 3
f = 1
for i in range(2, number + 1):
print(f' Task {name}: Compute factorial({i})...')
if raise_exception and i > 3:
print(f' Task {name}: raising Exception')
raise Exception(f'Bad Task {name}')
await asyncio.sleep(1)
f *= i
print(f'==>> Task {name} DONE: factorial({number}) = {f}')
return f
async def main():
tasks = [factorial('A', 5), # this will not be finished
factorial('B', 10, raise_exception=True),
factorial('C', 2)]
try:
results = await asyncio.gather(*tasks)
print('Results:', results)
except Exception as e:
print('Got an exception:', e)
asyncio.run(main())
这段代码在做什么,只是为了使其更简单,它定义了3个任务并在它们上调用
asyncio.gather()
。其中一项任务在完成另一项任务之前引发异常,而另一项任务尚未完成。实际上,我什至无法理解文档中所说的内容-如果在
gather
上等待的任务引发并捕获了异常,我什至无法获得返回的结果(即使其他任务以某种方式完成了) )。我是否有任何遗漏,或者文档有问题吗?
已使用Python 3.7.2进行了测试。
最佳答案
正如文档所预期的,我已经运行了您的代码并获得了以下输出。
Task C: Compute factorial(2)...
Task A: Compute factorial(2)...
Task B: Compute factorial(2)...
==>> Task C DONE: factorial(2) = 2
Task A: Compute factorial(3)...
Task B: Compute factorial(3)...
Task A: Compute factorial(4)...
Task B: Compute factorial(4)...
Task B: raising Exception
Got an exception: Bad Task B
Task A: Compute factorial(5)...
==>> Task A DONE: factorial(5) = 120
这是怎么回事
await asyncio.gater()
立即返回,并将print('Got an exception:', e)
返回到屏幕。 你的考试怎么了
正如@deceze所说,
在捕获到异常并返回
main()
后,您的程序立即退出。因此,任务A和C终止是因为整个过程死亡,而不是因为取消。要解决此问题,请将
await asyncio.sleep(20)
添加到main()
函数的末尾。