2017-09-13 114 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相同的功能。