python - 如何确保使用 asyncio.gather 执行所有任务?
问题描述
使用asyncio.gather
时,当其中一个任务引发异常时,所有任务都不会执行:
# coding: utf-8
import asyncio
async def foo(i):
await asyncio.sleep(0.1)
if i == 2:
print("2: 1/0")
1/0
print(i)
async def main():
futures = []
for i in range(1000):
futures.append(foo(i))
await asyncio.gather(*futures)
asyncio.run(main())
0
1
2: 1/0
3
4
5
6
7
[...]
501
502
503
504
Traceback (most recent call last):
File "<input>", line 24, in <module>
File "/usr/lib/python3.8/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "<input>", line 21, in main
File "<input>", line 9, in foo
ZeroDivisionError: division by zero
如何确保在退出之前执行所有任务asyncio.gather
?我知道这不是默认行为,asyncio.gather
因为如果我的一项任务从未完成,则永远不会引发异常。我的问题更多:我如何执行一组任务收集并等待所有完成/提升,然后再继续?
解决方案
我认为您想密切关注asyncio.gather 的文档:
如果 return_exceptions 为 False(默认值),则第一个引发的异常会立即传播到在 gather() 上等待的任务。aws 序列中的其他等待对象不会被取消,并将继续运行。
如果 return_exceptions 为 True,则将异常视为成功结果,并在结果列表中聚合。
根据我的阅读,看起来如果您要这样打电话asyncio.gather
...
await asyncio.gather(*futures, return_exceptions=True)
...你应该得到你想要的行为。
推荐阅读
- java - 如何使用 jersey 编写 REST API 方法来使用 json 对象的 json 格式
- phpmyadmin - wamp server 配置文件第561行包含s语法错误:参数service指定未知服务
- python - 如何从特定输入中排除输入?
- xamarin - Xmarin.forms iOS 检查捕获的照片是否包含人脸
- c# - 更新数据库 c# 控制台应用程序中的表行
- lex - /usr/bin/ld: 找不到 -ll collect2: 错误: ld 返回 1 退出状态
- asp.net-core - 请告诉我如何上传 Summernote 的文字图片
- javascript - 如何对使用赛普拉斯的 React 组件调用回调函数进行单元测试
- firebase - 在颤振飞镖应用程序中出现错误。未为“DocumentSnapshot”类型定义运算符“[]”。尝试定义运算符'[]'
- sql - 添加 ROW_NUMBER 到查询是否会自动排序?