The point of using
asyncio.Task(coro())
is to execute
coro
in the background while waiting for other tasks without explicitly waiting for it. According to Guido's slide, this means that a
Task
can make progress without waiting for it, as long as you wait for something else. For example, consider the following.
import asyncio
@asyncio.coroutine
def test1():
print("in test1")
@asyncio.coroutine
def dummy():
yield from asyncio.sleep(1)
print("dummy ran")
@asyncio.coroutine
def main():
test1()
yield from dummy()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出:
dummy ran
正如您所看到的,test1
实际上从未被执行,因为我们没有显式地在其上调用 yield from
。
现在,如果我们使用 asyncio.async
将 Task
实例包装在 test1
周围,则结果是不同的:
import asyncio
@asyncio.coroutine
def test1():
print("in test1")
@asyncio.coroutine
def dummy():
yield from asyncio.sleep(1)
print("dummy ran")
@asyncio.coroutine
def main():
asyncio.async(test1())
yield from dummy()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出:
in test1
dummy ran
因为使用
yield from asyncio.async(coro())
会比没有任何效益的
yield from coro()
慢,所以实际上没有使用
yield from asyncio.async(coro())
的实际理由;它引入了将
coro
添加到内部
asyncio
调度程序的开销,但这并不需要,因为使用
yield from
可以保证
coro
将被执行。如果你只想调用协程并等待它完成,那么直接
yield from
协程即可。
顺便说一下:
我正在使用
asyncio.async
*而不是直接使用
Task
因为文档推荐这样做:
不要直接创建Task
实例:使用async()
函数或BaseEventLoop.create_task()
方法。
*请注意,从Python 3.4.4起,asyncio.async
已被弃用,推荐使用asyncio.ensure_future
。
yield from coro()
来运行协程,在任务构建的情况下,例如async(coro())
将与其他协程并行执行。 - Andrew Svetlovyield from coro()
立即执行协程,而async(coro())
通过loop.call_soon()
调用安排执行。 - Andrew Svetlovyield from
,也不完全兼容asyncio。 - Andrew Svetlov