asyncio.gather 协程高级分组中的异常
Exceptions in high-level grouping of corountines with asyncio.gather
我目前正在做一个项目,我在其中启动了几个协同程序,我将它们与 asyncio.gather
组合在一起。然后,我将所有这些子组组合在一起,再次使用 asyncio.gather
.
除非发生错误,否则一切正常。错误不会传播到主程序,而 return_exceptions
关键字未设置为 True。
重现方法如下:
import asyncio
async def ok_task():
while True:
await asyncio.sleep(0)
async def error_task():
await asyncio.sleep(1)
print("crashed!")
raise RuntimeError
async def create_coros():
return asyncio.gather(ok_task(), error_task())
def main():
subgroup_1 = create_coros()
subgroup_2 = create_coros()
subgroup_3 = create_coros()
main_group = asyncio.gather(subgroup_1, subgroup_2, subgroup_3)
asyncio.get_event_loop().run_until_complete(
main_group
)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
main()
crashed!
在控制台上正确出现了 3 次,但没有引发 RuntimeError
。
但是,如果我用 return await asyncio.gather(ok_task(), error_task())
修改 create_coros
函数,则会出现异常行为。
谁能解释为什么没有额外的 await
就不会传播异常?
进行以下更改以使您的代码按预期工作。另一方面,如果我是你,我会尝试只使用一个 gather
并在那个 gather
.
中累积所有协程
import asyncio
async def ok_task():
"""Not infinite loop now"""
n = 10
while n:
await asyncio.sleep(0.5)
n -= 1
return 100 # let's return some number
async def error_task():
"""It always make problems"""
await asyncio.sleep(1)
print("crashed!")
raise RuntimeError("NOooo!!!")
async def create_coros():
"""Accumulate tasks here"""
# return_exceptions=True - since we expect errors
# should return some Coroutine which return result of
# await asyncio.gather(ok_task(), error_task(), return_exceptions=True)
# await is used to return appropriate datatype for gather function
# which expect coroutines as args
return await asyncio.gather(ok_task(), error_task(), return_exceptions=True)
async def amain():
# create several groups of coroutines
subgroup_1 = create_coros()
subgroup_2 = create_coros()
subgroup_3 = create_coros()
# gather expect coroutines
r = await asyncio.gather(subgroup_1, subgroup_2, subgroup_3)
print(f"Final Result: {r}")
if __name__ == "__main__":
asyncio.run(amain())
我目前正在做一个项目,我在其中启动了几个协同程序,我将它们与 asyncio.gather
组合在一起。然后,我将所有这些子组组合在一起,再次使用 asyncio.gather
.
除非发生错误,否则一切正常。错误不会传播到主程序,而 return_exceptions
关键字未设置为 True。
重现方法如下:
import asyncio
async def ok_task():
while True:
await asyncio.sleep(0)
async def error_task():
await asyncio.sleep(1)
print("crashed!")
raise RuntimeError
async def create_coros():
return asyncio.gather(ok_task(), error_task())
def main():
subgroup_1 = create_coros()
subgroup_2 = create_coros()
subgroup_3 = create_coros()
main_group = asyncio.gather(subgroup_1, subgroup_2, subgroup_3)
asyncio.get_event_loop().run_until_complete(
main_group
)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
main()
crashed!
在控制台上正确出现了 3 次,但没有引发 RuntimeError
。
但是,如果我用 return await asyncio.gather(ok_task(), error_task())
修改 create_coros
函数,则会出现异常行为。
谁能解释为什么没有额外的 await
就不会传播异常?
进行以下更改以使您的代码按预期工作。另一方面,如果我是你,我会尝试只使用一个 gather
并在那个 gather
.
import asyncio
async def ok_task():
"""Not infinite loop now"""
n = 10
while n:
await asyncio.sleep(0.5)
n -= 1
return 100 # let's return some number
async def error_task():
"""It always make problems"""
await asyncio.sleep(1)
print("crashed!")
raise RuntimeError("NOooo!!!")
async def create_coros():
"""Accumulate tasks here"""
# return_exceptions=True - since we expect errors
# should return some Coroutine which return result of
# await asyncio.gather(ok_task(), error_task(), return_exceptions=True)
# await is used to return appropriate datatype for gather function
# which expect coroutines as args
return await asyncio.gather(ok_task(), error_task(), return_exceptions=True)
async def amain():
# create several groups of coroutines
subgroup_1 = create_coros()
subgroup_2 = create_coros()
subgroup_3 = create_coros()
# gather expect coroutines
r = await asyncio.gather(subgroup_1, subgroup_2, subgroup_3)
print(f"Final Result: {r}")
if __name__ == "__main__":
asyncio.run(amain())