我从文档中了解到asyncio.Tasks作为asyncio.Future子类,将存储在其中引发的异常,并且可以在我闲暇时检索它们。
但是,在此示例代码中,会立即引发异常:
import asyncio
async def bad_task():
raise Exception()
async def test():
loop = asyncio.get_event_loop()
task = loop.create_task(bad_task())
await task
# I would expect to get here
exp = task.exception()
# but we never do because the function exits on line 3
loop = asyncio.get_event_loop()
loop.run_until_complete(test())
loop.close()
示例输出(Python 3.6.5):
python3 ./test.py
Traceback (most recent call last):
File "./test.py", line 15, in <module>
loop.run_until_complete(test())
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 468, in run_until_complete
return future.result()
File "./test.py", line 9, in test
await task
File "./test.py", line 4, in bad_task
raise Exception()
Exception
这是创造和创造的怪癖吗?已经在异步代码中调用任务?
答案 0 :(得分:5)
await
将引发任务抛出的任何异常,因为它意味着使异步代码看起来几乎与同步代码完全相同。如果要捕获它们,可以使用普通的try...except
子句。
答案 1 :(得分:2)
Matti解释说,协程引发的例外情况会传播到等待网站。这是故意的,因为它确保默认情况下不会以无提示方式传递错误。但是,如果需要这样做,那么在没有立即访问其结果/异常的情况下等待任务完成肯定是可能。
通过使用小型中间Future
:
async def test():
loop = asyncio.get_event_loop()
task = loop.create_task(bad_task())
task_done = loop.create_future() # you could also use asyncio.Event
# Arrange for task_done to complete once task completes.
task.add_done_callback(task_done.set_result)
# Wait for the task to complete. Since we're not obtaining its
# result, this won't raise no matter what bad_task() does...
await task_done
# ...and this will work as expected.
exp = task.exception()