问题描述
这是取消任务的示例:
import asyncio
async def some_func():
await asyncio.sleep(2)
print('Haha! Task keeps running!')
await asyncio.sleep(2)
async def cancel(task):
await asyncio.sleep(1)
task.cancel()
async def main():
func_task = asyncio.ensure_future(some_func())
cancel_task = asyncio.ensure_future(cancel(func_task))
try:
await func_task
except asyncio.CancelledError:
print('Task cancelled as expected')
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# Task cancelled as expected
# [Finished in 1.2s]
一切正常,任务被取消.如果 CancelledError
被捕获在 some_func
中,任务不会被取消:
It works ok, task was cancelled. If CancelledError
caught inside some_func
task wouldn't be cancelled:
async def some_func():
try:
await asyncio.sleep(2)
except:
pass
print('Haha! Task keeps running!')
await asyncio.sleep(2)
# Haha! Task keeps running!
# [Finished in 3.2s]
很容易忘记我不应该在异步代码中的任何地方抑制异常(例如,some_func
可以是第三方代码),但任务应该取消.反正我能做到吗?或者忽略 CancelledError
意味着任务根本无法取消?
It can be easy to forgot I shouldn't suppress exceptions anywhere inside async code (or some_func
can be third party code, for example), but task should be cancelled. Is there anyway I can do that? Or ignored CancelledError
means task can't be cancelled at all?
推荐答案
您无法取消抑制 CancelledError
的任务.这类似于无法关闭忽略 GeneratorExit
的生成器.
You cannot cancel task that suppresses CancelledError
.This is similar to impossibility to close generator which ignores GeneratorExit
.
这是故意行为.任务可能想要在取消时做一些额外的工作(例如资源清理),因此捕获 CancelledError
可能是个好主意,但抑制通常是编程错误的迹象.
This is intentional behavior. Task may want to do some extra work (e.g. resource cleanup) on cancelling, thus catching CancelledError
may be good idea but suppressing usually is sign of programming error.
如果您有不妥协的打算,Python 通常允许您用自己的脚射击.
Python usually allows you to shoot own feet if you have uncompromising intention to do this.
捕获所有异常甚至禁止通过按<Ctrl+C>
来关闭python进程,因为它在内部被翻译成KeyboardInterrupt
.
Catching all exceptions even forbids closing python process by pressing <Ctrl+C>
because it's translated into KeyboardInterrupt
internally.
这篇关于即使忽略了CancelledError,如何取消任务执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!