python - Python asyncio:处理gather()中的异常-文档不清楚?
问题描述
asyncio.gather的文档说
如果 return_exceptions 是
False
(默认),则第一个引发的异常会立即传播到 await on 的任务gather()
。aws 序列中的其他等待对象不会被取消,并将继续运行。
但是,从一个简单的测试看来,如果其中一个任务在 return_exceptions 为时引发异常,则False
所有其他可等待对象都将被取消(或者更准确地说,如果我不清楚术语,其他可等待对象不会完成他们的工作):
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
这是怎么回事
- 任务 A、B 和 C 被提交到队列中;
- 所有任务都在运行,而 C 最早完成。
- 任务 B 引发和异常。
await asyncio.gater()
立即返回print('Got an exception:', e)
屏幕。- 任务 A 继续运行并打印“==>> 任务 A DONE ...”
你的测试有什么问题
main()
正如@deceze 评论的那样,您的程序在异常被捕获并返回后立即退出。因此,任务 A 和 C 被终止是因为整个进程死亡,而不是因为取消。
要修复它,请添加await asyncio.sleep(20)
到main()
函数的末尾。
推荐阅读
- rest - Atlassian Jira - 401 仅在使用查询参数时
- openedge - 带有动态文件类型过滤器的 SYSTEM-DIALOG GET-FILE
- javascript - 如何等待角度订阅
- docker - Docker 网络/服务问题
- swift - Linux 是否支持 URLSession?
- python - 通过 multiprocessing.pool 的 Python3 并行代码比顺序代码慢
- vba - 打开文件中的宏如果你在开会,点击“确定”,如果没有,在excel中再次提及
- logistic-regression - 如何使用主成分分析进行逻辑回归
- android - 如何从 firebase 数据库中洗牌并显示有限的值?
- java - 在java中查找阿姆斯特朗数