提问人:Claudio_G 提问时间:11/15/2023 最后编辑:Claudio_G 更新时间:11/15/2023 访问量:26
Python asyncio 任务取消消息未传播
Python asyncio task cancel message not propagated
问:
我很难理解异步是如何的。CancelledError 正在传播。我有以下代码:
import asyncio
import traceback
async def uselessTask():
return await asyncio.sleep(10)
async def mainAsync():
task = asyncio.create_task(uselessTask())
asyncio.get_running_loop().call_later(1, lambda: task.cancel("CANCELLING USELESS TASK"))
try:
results = await task
except asyncio.CancelledError as exc:
print(f"Caught exception {type(exc).__name__}: {exc}")
print(f"Task: {task}")
traceback.print_exc()
return
asyncio.run(mainAsync())
上述操作的执行会产生以下结果(对于 python 3.9.6 和 3.10.7):
Caught exception CancelledError:
Task: <Task cancelled name='Task-2' coro=<uselessTask() done, defined at C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py:5>>
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 6, in uselessTask
return await asyncio.sleep(10)
File "C:\Users\<user>\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 605, in sleep
return await future
asyncio.exceptions.CancelledError: CANCELLING USELESS TASK
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 14, in mainAsync
results = await task
asyncio.exceptions.CancelledError
Process finished with exit code 0
但是,我的期望是,在执行期间捕获的异常与任务中发生的异常完全相同,因此会显示相同的取消消息“取消无用任务”。results = await task
但是,正如您所看到的,asyncio 上没有取消消息。CancelledError 由使用任务导致。
我不明白的另一件奇怪的事情是,如果我打破异常块并检查变量,我会看到任务被取消,但_cancel_message是空的。task
我不完全理解为什么异常会以这种方式冒泡,或者为什么除了在任务中之外看不到取消消息(例如,如果我尝试:除了:uselessTask()函数,则捕获的异常有消息)。此外,回溯消息“在处理上述异常期间,发生了另一个异常:”似乎表明没有发生异常链接,因为链接产生“上述异常是以下异常的直接原因:”
我正在浏览 python 文档,但我似乎无法将我所看到的内容与所写的内容相关联。
编辑:
只是为了更好地展示我的期望:
import asyncio
import traceback
async def uselessTask():
try:
await asyncio.sleep(10)
except asyncio.CancelledError as exc:
raise RuntimeError(*exc.args)
return
async def mainAsync():
task = asyncio.create_task(uselessTask())
asyncio.get_running_loop().call_later(1, lambda: task.cancel("CANCELLING USELESS TASK"))
try:
results = await task
except (asyncio.CancelledError, RuntimeError) as exc:
print(f"Caught exception {type(exc).__name__}: {exc}")
print(f"Task: {task}")
traceback.print_exc()
return
asyncio.run(mainAsync())
此代码返回
Caught exception RuntimeError: CANCELLING USELESS TASK
Task: <Task finished name='Task-2' coro=<uselessTask() done, defined at C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py:5> exception=RuntimeError('CANCELLING USELESS TASK')>
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 7, in uselessTask
await asyncio.sleep(10)
File "C:\Users\<user>\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 605, in sleep
return await future
asyncio.exceptions.CancelledError: CANCELLING USELESS TASK
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 20, in mainAsync
results = await task
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 9, in uselessTask
raise RuntimeError(*exc.args)
RuntimeError: CANCELLING USELESS TASK
Process finished with exit code 0
另一方面,此代码
import asyncio
import traceback
async def uselessTask():
try:
await asyncio.sleep(10)
except asyncio.CancelledError as exc:
raise asyncio.CancelledError(*exc.args)
return
async def mainAsync():
task = asyncio.create_task(uselessTask())
asyncio.get_running_loop().call_later(1, lambda: task.cancel("CANCELLING USELESS TASK"))
try:
results = await task
except (asyncio.CancelledError, RuntimeError) as exc:
print(f"Caught exception {type(exc).__name__}: {exc}")
print(f"Task: {task}")
traceback.print_exc()
return
asyncio.run(mainAsync())
返回以下内容:
Caught exception CancelledError:
Task: <Task cancelled name='Task-2' coro=<uselessTask() done, defined at C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py:5>>
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 7, in uselessTask
await asyncio.sleep(10)
File "C:\Users\<user>\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 605, in sleep
return await future
asyncio.exceptions.CancelledError: CANCELLING USELESS TASK
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 9, in uselessTask
raise asyncio.CancelledError(*exc.args)
asyncio.exceptions.CancelledError: CANCELLING USELESS TASK
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\<user>\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_22.py", line 20, in mainAsync
results = await task
asyncio.exceptions.CancelledError
Process finished with exit code 0
如您所见,解开任务结果会引发 asyncio。CancelledError,但消息现在已消失,而在引发任何其他异常时,解包会保留 Exception 参数
答: 暂无答案
评论