2017-09-13 140 views
2

使用python 3.5或更高版本,将await直接应用于未来或任务,并将其与asyncio.wait_for包装在一起之间有什么区别吗?关于什么时候适合使用wait_for这个文档还不清楚,我想知道它是否是旧的基于生成器的库的遗迹。 以下的测试程序出现显示没有区别,但这并不能证明任何东西。'await future'和'await asyncio.wait_for(future,None)'之间有区别吗?

import asyncio 

async def task_one(): 
    await asyncio.sleep(0.1) 
    return 1 

async def task_two(): 
    await asyncio.sleep(0.1) 
    return 2 

async def test(loop): 
    t1 = loop.create_task(task_one()) 
    t2 = loop.create_task(task_two()) 

    print(repr(await t1)) 
    print(repr(await asyncio.wait_for(t2, None))) 

def main(): 
    loop = asyncio.get_event_loop() 
    try: 
     loop.run_until_complete(test(loop)) 
    finally: 
     loop.close() 

main() 

回答

2

wait_for给两个功能:

  1. 允许定义超时,
  2. 让你指定的循环

你举的例子:

await f1 
await asyncio.wait_for(f1, None) # or simply asyncio.wait_for(f1) 

之外的开销调用额外的包装器(wait_for),它们是相同的(https://github.com/python/cpython/blob/master/Lib/asyncio/tasks.py#L318)。

awaits都将无限期地等待结果(或例外)。在这种情况下,普通await更合适。

另一方面,如果您提供超时参数,它将等待时间限制的结果。如果超过超时时间,将会增加TimeoutError,未来将被取消。

async def my_func(): 
    await asyncio.sleep(10) 
    return 'OK' 

# will wait 10s 
await my_func() 

# will wait only 5 seconds and then will raise TimeoutError 
await asyncio.wait_for(my_func(), 5) 

另一件事是循环参数。在大多数情况下,你不应该被打扰,用例是有限的:注入不同的循环测试,运行其他循环...

该参数的问题是,所有后续任务/功能也应该有环传承下去......

更多信息https://github.com/python/asyncio/issues/362

+0

你能想到一个能够指定循环的重要情况吗? – zwol

2

不幸的是,蟒蛇文档是有点不清楚这里,但如果你看看到sources它很明显:

在违背await协程asyncio.wait_for()只允许等待有限的时间直到将来/任务完成。如果在此时间内未完成,则会产生concurrent.futures.TimeoutError

可以将此超时指定为第二个参数。在你的示例代码中,这个参数是None,其结果是正好是与直接应用await/yield from相同的功能。

相关问题