的documentation for asyncio.wait_for
規定,將取消基礎任務,然後從wait_for
調用本身提高TimeoutError
:未來或協程
返回結果。發生超時時, 取消該任務並提出asyncio.TimeoutError
。
而且你是正確的,任務取消can indeed be intercepted:
[Task.cancel
]排列爲CancelledError
被拋進通過事件循環包裹 協程在下一個週期。協程 有機會使用 try
/except
/finally
清除甚至拒絕請求。
請注意,文檔指定將CancelledError
引入協程,而不是TimeoutError
。
如果你作出這樣的調整,工作的事情你期望的方式:
import asyncio
@asyncio.coroutine
def toTimeout():
try:
i = 0
while True:
print("iteration ", i, "......"); i += 1
yield from asyncio.sleep(1)
except asyncio.CancelledError:
print("timed out")
def main():
#... do some stuff
yield from asyncio.wait_for(toTimeout(), 3)
#... do some more stuff
asyncio.get_event_loop().run_until_complete(main())
輸出:
iteration 0 ......
iteration 1 ......
iteration 2 ......
timed out
Traceback (most recent call last):
File "aio.py", line 18, in <module>
asyncio.get_event_loop().run_until_complete(main())
File "/usr/lib/python3.4/asyncio/base_events.py", line 316, in run_until_complete
return future.result()
File "/usr/lib/python3.4/asyncio/futures.py", line 275, in result
raise self._exception
File "/usr/lib/python3.4/asyncio/tasks.py", line 238, in _step
result = next(coro)
File "aio.py", line 15, in main
yield from asyncio.wait_for(toTimeout(), 3)
File "/usr/lib/python3.4/asyncio/tasks.py", line 381, in wait_for
raise futures.TimeoutError()
concurrent.futures._base.TimeoutError
正如你可以看到,現在'timed out'
獲取TimeoutError
前打印由wait_for
提高。