本文介绍了即使忽略了CancelledError,如何取消任务执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是取消任务的示例:

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,如何取消任务执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 03:11