为什么 asyncio.timeout 在包装异步生成器时不起作用,如下例所示?
async def generate_many_numbers():
for i in range(1000000000):
yield i
async def main2():
async with asyncio.timeout(1):
async for number in generate_many_numbers():
print(number)
asyncio.run(main2())
这是否与此处描述的问题相同? https://peps.python.org/pep-0789/
编辑: 我注意到添加异步虚拟睡眠有助于...
async def generate_many_numbers():
for i in range(1000000000):
await asyncio.sleep(0)
yield i
async def iterate_through_numbers():
async for number in generate_many_numbers():
print(number)
async def main2():
async with asyncio.timeout(1):
async for number in generate_many_numbers():
print(number)
async def main3():
try:
await asyncio.wait_for(iterate_through_numbers(), timeout=1)
except asyncio.TimeoutError:
print("The task timed out!")
函数
generate_many_numbers
永远不会将控制返回给事件循环,因此 asyncio.timeout
没有机会在完成之前取消它。
要将控制权返回给事件循环,必须有(在最简单的情况下)一个
await
语句。如果没有其他原因需要使用 await
,您可以使用 await asyncio.sleep(0)
,请参阅例如为什么 asyncio.sleep(0) 使我的代码更快?
我认为这与 PEP 789 无关。