asyncio等待多个任务超时和取消

时间:2020-08-25 17:04:34

标签: python-3.x python-asyncio

我有一些代码可以像这样循环运行多个任务:

    done, running = await asyncio.wait(running, timeout=timeout_seconds,
                                       return_when=asyncio.FIRST_COMPLETED)

我需要能够确定其中哪些超时。根据{{​​3}}:

请注意,此函数不会引发asyncio.TimeoutError。发生超时时未完成的期货或任务仅在第二组中返回。

我可以改用wait_for(),但是该函数只接受一个等待的对象,而我需要指定多个。有什么方法可以确定我传递给wait()的一组等待中的哪一个造成了超时?

或者,有没有一种方法可以将wait_for()与多个等待项一起使用?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用这些技巧,可能不是很好的解决方案:

import asyncio

async def foo():
    return 42

async def need_some_sleep():
    await asyncio.sleep(1000)
    return 42


async def coro_wrapper(coro):
    result = await asyncio.wait_for(coro(), timeout=10)
    return result

loop = asyncio.get_event_loop()

done, running = loop.run_until_complete(asyncio.wait(
    [coro_wrapper(foo), coro_wrapper(need_some_sleep)],
    return_when=asyncio.FIRST_COMPLETED
    )
)

for item in done:
    print(item.result())

print(done, running)

答案 1 :(得分:0)

我是这样做的:

done, pending = await asyncio.wait({
    asyncio.create_task(task, name=index)
        for index, task in enumerate([
            my_coroutine(),
            my_coroutine(),
            my_coroutine(),
        ])
    },
    return_when=asyncio.FIRST_COMPLETED
)

num = next(t.get_name() for t in done)

if num == 2:
    pass

使用 enumerate 为创建的任务命名。