协程和异步/等待

时间:2020-04-28 16:58:49

标签: python python-3.x async-await python-asyncio

我遇到了asyncIO问题。我想让我的程序在运行协程的任务时执行某些操作,并在协程完成后退出。

我已将问题简化为以下代码段:

import time
import asyncio


async def long_task():
    time.sleep(3)
    return "DONE !"


def do_while_idle():
    loop = asyncio.get_event_loop()
    task = loop.create_task(long_task)
    while not task.done():
        time.sleep(1)
        print("IDLE")
    print(task.result())


do_while_idle()

我想要这个输出:

IDLE
IDLE
IDLE
DONE !

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以这样处理:

import asyncio

async def do_while_idle():
    for _ in range(3):
        print("IDLE")
        await asyncio.sleep(1)

    return "Done stuff while idling"

async def long_task():
    await asyncio.sleep(3)
    return "DONE !"

async def main():
    task = asyncio.create_task(long_task())
    task2 = asyncio.create_task(do_while_idle())
    done, _ = await asyncio.wait({task, task2})

    if task in done:
        task2.cancel()
        print(task.result())

asyncio.run(main())

空闲应该是另一个任务,此代码段等待long_task完成,然后取消空闲任务。您还可以像这样检查空转和long_task是否都已完成:

async def main():
    task = asyncio.create_task(long_task())
    task2 = asyncio.create_task(do_while_idle())
    done, _ = await asyncio.wait({task, task2})

    if task and task2 in done:
        print(task.result(), task2.result())

第一个代码段将为您提供所需的结果:

IDLE
IDLE
IDLE
DONE !

答案 1 :(得分:1)

像宫城先生({3}}一样,您必须等待asyncio.sleep()而不是致电time.sleep(),并消除其他障碍,例如通过将requests的使用替换为points out

要在任务运行期间执行一些空闲代码,可以将空闲代码编写为无限循环,而与主要任务无关。 do_while_idle可以作为任务开始空闲循环,直接等待long_task(),然后只需取消空闲循环即可:

import asyncio

async def long_task():
    await asyncio.sleep(3)
    return "DONE !"

async def idle():
    while True:
        await asyncio.sleep(1)
        print("IDLE")

async def do_while_idle():
    idle_task = asyncio.create_task(idle())
    print(await long_task())
    idle_task.cancel()

asyncio.run(do_while_idle())