python - 不确定为什么异步任务在事件循环之外完成

标签 python python-asyncio

我无法弄清楚这种行为。我使用的是 Python 3.6.4。

在这里,我有 4 个异步函数。在 test1 中,我调用 asyncio.ensure_future(TestAsync()) 并将协程转换为任务。在其他(test2test3test4)上,我没有调用ensure_future(),我只是创建了协程并将它们传递到一个列表中,然后将该列表传递到事件循环中。

我将 test1 排除在传递到事件循环的列表之外。所以我的印象是 test1 不会运行,但在我的输出中,它显然运行了。有人可以向我解释为什么 test1 不在事件循环内时仍然输出吗?

import asyncio
import random

async def TestAsync():
    print("Test 1 started")
    wait = random.randint(1, 10)
    await asyncio.sleep(wait)
    print("Test 1 done awaited: " + str(wait))

async def TestAsync2():
    print("Test 2 started")
    wait = random.randint(1, 10)
    await asyncio.sleep(wait)
    print("Test 2 done awaited: " + str(wait))

async def TestAsync3():
    print("Test 3 started")
    wait = random.randint(1, 10)
    await asyncio.sleep(wait)
    print("Test 3 done awaited: " + str(wait))

async def TestAsync4():
    print("Test 4 started")
    wait = random.randint(1, 10)
    await asyncio.sleep(wait)
    print("Test 4 done awaited: " + str(wait))

test1 = asyncio.ensure_future(TestAsync())
test2 = TestAsync2()
test3 = TestAsync3()
test4 = TestAsync4()
tasklist = [test2, test3, test4]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasklist))

输出

Test 1 started.    <--This is the one wasn't in the event loop
Test 3 started
Test 4 started
Test 2 started
Test 4 done awaited: 1
Test 3 done awaited: 2
Test 1 done awaited: 7
Test 2 done awaited: 10

最佳答案

正如其他人指出的那样,ensure_future会将任务添加到默认事件循环中,以便在下一次机会时运行。 ensure_future 将任意可等待转换为 asyncio.Future ,在协程对象的情况下,这是通过将其包装到 Task 中来完成的。 (Future 的子类),具有 callcreate_task。无论调用 ensure_future 的代码是否存储对返回的 future 的引用,该任务都将在下次事件循环旋转时运行。

另一个需要注意的重要事项是 run_until_complete(x) 表示“将 x 提交到事件循环并运行循环直到 x Completes”,它不会阻止调用 run_until_complete 之前添加的任务运行。

在Python 3.7中,有一个新函数asyncio.run创建一个新的事件循环并向其提交给定的协程。将 asyncio.run_until_complete 替换为 asyncio.run 将产生您期望的行为。

关于python - 不确定为什么异步任务在事件循环之外完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52251325/

相关文章:

python - Asyncio 异步运行函数

python - 使用字典作为查找表

python - 不一致的页面在 Internet Explorer 中显示过期消息

python - 列表索引类型错误

python - ElasticSearch,size参数不适用于helpers.scan函数

python - python可以控制itunes之类的应用吗?

python - 异步 : Is it possible to cancel a future been run by an Executor?

python - 在另一个文件中使用 Asyncio 循环引用

python - asyncio.TimeoutError 永远不会引发

python - 为什么我需要将 python 协程包装到任务中/何时使用任务或协程?