关键问题:asyncio.wait(aws,timeout=1,return_when=FIRST_COMPLETED)
是否有简单的方法来检查返回的任务是否超时?
这是一个扩展的问题。
场景是这样的:
因此,为了更快地获取数据,我需要限制协程的数量。检查返回的页面。还有超时。
目前有两种简单的方法。
1.与线程类似,使用队列构建协程池+ 10个无限循环coro。我不太喜欢实际上,这种方法非常快速。
2.我尝试使用异步python3.7的高级API,尝试使用while tasks
和asyncio.wait
和return_when
简化程序的结构。
在这里,我遇到了如何找到协程超时的问题。
我建立了一个简单的演示:
import asyncio
async def test(delaytime):
print(f"begin {delaytime}")
await asyncio.sleep(delaytime )
print(f"finish {delaytime} ")
async def main():
# the number of tasks is unknow,range(10) is just a demo
allts = list(range(10))
ts = []
while len(ts)<5:
arg = allts.pop()
t = asyncio.create_task(test(arg))
t.arg = arg
ts.append(t)
while ts:
dones,pendings = await asyncio.wait(ts,timeout=2,return_when=asyncio.FIRST_COMPLETED)
for t in dones:
# if check t.result() is error , i can append ts again
print(t.arg,"is done")
ts.remove(t)
while len(ts)<5:
if len(allts):
arg = allts.pop()
t = asyncio.create_task(test(arg))
t.arg = arg
ts.append(t)
else:
break
# for t in pendings:
# # if can check t is timeout , i can append ts again
# pass
if __name__=="__main__":
asyncio.run(main())
调试之后,我知道return_when=asyncio.FIRST_COMPLETED
返回的任务asyncio.wait
在待处理的任务中,除了已完成的任务。
但是,我无法确定哪个任务超时。
我曾考虑过使用wait_for
,但是wait_for
没有return_when
参数。
是否有一种简单的方法来确定超时任务以便重新加入ts
?
答案 0 :(得分:1)
问题在于,使用wait(return_when=FIRST_COMPLETED)
的方法与timeout
的使用根本不兼容。由于不同的任务在不同的时间开始执行,因此一个timeout
参数显然不能应用于所有任务。如果要使用return_when=FIRST_COMPLETED
,请将每个任务包装在asyncio.wait_for
中:
t = asyncio.create_task(asyncio.wait_for(test(arg), 2))
然后,当任务完成时,您可以使用t.exception()
测试它是否超时,在这种情况下它将返回asyncio.TimeoutError
。此检查只能在完成任务中执行。