我正在阅读asyncio文档以了解任务取消,并且遇到this-
要取消正在运行的Task,请使用cancel()方法。调用它将导致Task向包装的协程中抛出CancelledError异常。如果协程在取消过程中等待Future对象,则Future对象将被取消。
cancelled()可用于检查任务是否已取消。如果包装的协程没有抑制CancelledError异常,并且实际上已取消,则该方法返回True。
我在这里有几个问题-
包装的协程是否称为取消的协程?让我们在这里举个例子-
async def wrapped_coroutine():
for task in asyncio.Task.all_tasks():
task.cancel()
wrapped_coroutine()
是包装好的协程,任务将在该协程中引发异常?
何时将引发此异常?在哪里?
抑制异常在这里意味着什么?这是否意味着-
async def wrapped_coroutine():
for task in asyncio.Task.all_tasks():
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Task cancelled")
如果没有,请提供一个示例来说明如何抑制此异常。
还有一个不相关的(与取消任务有关),当我取消这些任务时如何从这些任务中检索异常,所以我看不到-
Task exception was never retrieved future:
是在task.cancel()
之前还是在try
之前的await task
中(在上面的示例中)?
答案 0 :(得分:1)
看文档https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel中给出的示例中的代码:
async def cancel_me():
print('cancel_me(): before sleep')
try:
# Wait for 1 hour
await asyncio.sleep(3600)
except asyncio.CancelledError:
print('cancel_me(): cancel sleep')
raise
finally:
print('cancel_me(): after sleep')
async def main():
# Create a "cancel_me" Task
task = asyncio.create_task(cancel_me())
# Wait for 1 second
await asyncio.sleep(1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("main(): cancel_me is cancelled now")
asyncio.run(main())
回答您的问题:
cancel_me()
; .cancel()
在main()
中被调用。task.cancel()
之后引发此异常。它被扔进协程中,在示例中被捕获,然后重新引发以被抛出并陷入等待的例程中。cancel_me()
在捕获异常后不会重新引发异常。正如cancelled()
的文档所述:“当使用cancel()请求取消时,任务被取消,并且包装的协程将抛出的CancelledError异常传播到其中。” https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancelled