'await future' 和 'await asyncio.wait_for(future, None)' 有区别吗?
Is there a difference between 'await future' and 'await asyncio.wait_for(future, None)'?
对于 python 3.5 或更高版本,直接将 await
应用于未来或任务与使用 asyncio.wait_for
包装它之间有什么区别吗?该文档不清楚何时适合使用 wait_for
,我想知道它是否是旧的基于生成器的库的遗迹。下面的测试程序看起来没有区别,但这并不能真正证明什么。
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()
不幸的是,python 文档在这里有点不清楚,但是如果您查看 sources,它非常明显:
与 await
相反,协程 asyncio.wait_for()
只允许等待有限的时间,直到 future/task 完成。如果在此时间内未完成,则会引发 concurrent.futures.TimeoutError
。
这个超时可以指定为第二个参数。在您的示例代码中,此 timeout
参数是 None
,它导致 完全 与直接应用 await
/yield from
相同的功能。
wait_for
提供了另外两个功能:
- 允许定义超时,
- 让你指定循环
你的例子:
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)
另一件事是循环参数。在大多数情况下你不应该被打扰,用例是有限的:为测试注入不同的循环,运行 其他循环......
此参数的问题是,所有后续 tasks/functions 也应该传递该循环...
更多信息https://github.com/python/asyncio/issues/362
对于 python 3.5 或更高版本,直接将 await
应用于未来或任务与使用 asyncio.wait_for
包装它之间有什么区别吗?该文档不清楚何时适合使用 wait_for
,我想知道它是否是旧的基于生成器的库的遗迹。下面的测试程序看起来没有区别,但这并不能真正证明什么。
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()
不幸的是,python 文档在这里有点不清楚,但是如果您查看 sources,它非常明显:
与 await
相反,协程 asyncio.wait_for()
只允许等待有限的时间,直到 future/task 完成。如果在此时间内未完成,则会引发 concurrent.futures.TimeoutError
。
这个超时可以指定为第二个参数。在您的示例代码中,此 timeout
参数是 None
,它导致 完全 与直接应用 await
/yield from
相同的功能。
wait_for
提供了另外两个功能:
- 允许定义超时,
- 让你指定循环
你的例子:
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)
另一件事是循环参数。在大多数情况下你不应该被打扰,用例是有限的:为测试注入不同的循环,运行 其他循环......
此参数的问题是,所有后续 tasks/functions 也应该传递该循环...
更多信息https://github.com/python/asyncio/issues/362