为何Asyncio待完成任务总数始终为len+1?请求排查错误
问题原因与修复方案
核心错误点
你存在两个关键问题:
传递函数对象而非协程实例给
ensure_futureasyncio.ensure_future需要接收协程实例(调用async函数后的结果),但你传递的是do_something函数本身,而非do_something()。这会导致asyncio创建一个无效任务,加上do_something自身运行时的任务,就会出现计数多1的情况。asyncio.all_tasks()包含当前执行的任务
即使修复第一个问题,len(asyncio.all_tasks())也会把当前正在运行的do_something任务算进去,所以如果只有这一个任务在运行,计数会是1而非0。
修复后的代码
import asyncio async def my_routine(): # 模拟业务协程逻辑 await asyncio.sleep(0.1) return "completed" async def do_something(): ret = await my_routine() # 排除当前任务,统计其余待完成任务 remaining_tasks = asyncio.all_tasks() - {asyncio.current_task()} missing = f'Items to completion: {len(remaining_tasks)}' print(missing) return ret # 传递协程实例而非函数对象 task = asyncio.ensure_future(do_something()) # 启动事件循环执行任务 asyncio.run(asyncio.wait([task]))
说明
- 调用
do_something()生成协程实例后再传给ensure_future,才能创建有效任务。 - 通过
asyncio.all_tasks() - {asyncio.current_task()}排除当前执行的任务,得到真实的剩余待完成任务数量。
内容的提问来源于stack exchange,提问作者Andrea Moro
相关产品推荐
相关产品推荐

