问题
Lets assume I have a simple code:
import asyncio
async def exc():
print(1 / 0)
loop = asyncio.get_event_loop()
loop.create_task(exc())
try:
loop.run_forever()
except KeyboardInterrupt:
loop.stop()
loop.close()
If I run it, I get error message immediately
Task exception was never retrieved
future: <Task finished coro=<exc() done, defined at qq.py:4> exception=ZeroDivisionError('division by zero',)>
Traceback (most recent call last):
File "qq.py", line 5, in exc
print(1 / 0)
ZeroDivisionError: division by zero
But, if I change loop.create_task(exc())
to task = loop.create_task(exc())
I'll get the same error message after click ctrl+c
Why does task assignment change the time of output of error?
回答1:
A Exception in the Task (of underlying asyncio.Future
to be precise) can be retrieved with Future.exception()
. If it's not retrieved, the exception will be handled at release of the Future
object with eventloop's call_exception_handler.
So, as @dim pointed, while the Task has reference (assigned to variable in your case) it's not going be freed, therefore del task_future
won't be called, loop's handler won't be executed either.
来源:https://stackoverflow.com/questions/46890646/asyncio-weirdness-of-task-exception-was-never-retrieved