运行 任务创建和异步等待之间的代码

Running code between task creation and await with asyncio

使用 asyncio 是否可以创建一个任务,然后继续执行“主要”代码并稍后等待任务结果?

考虑以下代码

from functools import reduce
import asyncio

async def a_task():
    print('a_task(): before sleep')
    # waiting for something to happen
    await asyncio.sleep(30)
    print('a_task(): after sleep')
    return 42

async def main():
    # Create a Task
    print('main() before create_task')
    task = asyncio.create_task(a_task())
    print('main() task created')

    print('Doing stuff here between task creation and await')
    # Computing 200000! should take few seconds... 
    # use a smaller number if its too slow on your machine
    x = reduce(lambda a,b: a*b, range(1, 200000))
    print('Stuff done')

    print('main() awaiting task')
    task_result = await task
    print('main() task awaited')
    return task_result

#%%
if __name__ == '__main__':
    results = asyncio.run(main())
    print(results)

这个returns

main() before create_task
main() task created
Doing stuff here between task creation and await
Stuff done
main() awaiting task
a_task(): before sleep   <<---- Task only starts running here!!
a_task(): after sleep
main() task awaited
42

a_task是在我们开始计算200000!之前创建的,但它只在我们调用await task时执行。有没有可能让a_task开始到运行之前我们开始计算200000!并将其 运行ning 置于后台?

我看了the doc, , this,等等...他们都提到task应该用来在后台执行代码,但我不明白如何运行 就不用挂主代码了。

我认为这里的问题如下:使用 create_task 创建任务不会安排它立即执行:它需要一个 await 或类似的东西来触发切换事件循环开始 运行 一些不同的东西。在您当前的代码中,任务的创建之后是同步代码,在这种情况下,事件循环无法暂停 main 的执行并启动 运行 任务。确保其行为符合您预期的一种方法是将 asyncio.sleep(0) 放在 运行 阶乘计算之前。这样,当 main() 遇到 await 时,事件循环将暂停执行 main 并切换到 a_task.

您可能感兴趣的其他方法是使用 asyncio.gather docs link 安排多个异步任务,然后暂停 main 的执行并等待所有任务完成完成。

from functools import reduce
import asyncio


async def a_task():
    print("a_task(): before sleep")
    # waiting for something to happen
    await asyncio.sleep(30)
    print("a_task(): after sleep")
    return 42


async def doing_something_else():
    print("We start doing something else")
    x = reduce(lambda a, b: a * b, range(1, 200000))
    print("We finish doing something else")


async def main():
    # Create a Task
    print("main() before create_task")
    task = asyncio.create_task(a_task())
    print("main() task created")
    print("main() before create_task 2")
    task_2 = asyncio.create_task(doing_something_else())
    print("main() task 2 created")

    print("main() gathering tasks")
    # task_result = await task
    await asyncio.gather(task, task_2)
    print("main() tasks finished")
    # return task_result


#%%
if __name__ == "__main__":
    results = asyncio.run(main())
    print(results)