Python Asyncio 任务取消

标签 python python-3.x asynchronous python-asyncio

我正在阅读任务取消的 asyncio 文档,我发现了 this -

To cancel a running Task use the cancel() method. Calling it will cause the Task to throw a CancelledError exception into the wrapped coroutine. If a coroutine is awaiting on a Future object during cancellation, the Future object will be cancelled.

cancelled() can be used to check if the Task was cancelled. The method returns True if the wrapped coroutine did not suppress the CancelledError exception and was actually cancelled.

我有几个问题 -

  • 包装协程是调用cancel的协程吗?让我们举个例子 -

    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() 之前还是在 await task 之前的 try 中(在上面的示例中)?

最佳答案

查看文档 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的协程吗?”
    不是,这里的包装的协程是cancel_me().cancel()main() 中调用。
  • “什么时候抛出这个异常?在哪里?”
    调用task.cancel()后抛出这个异常。它被扔到协程内部,在示例中被捕获,然后被重新引发以被抛出并在等待例程中被捕获。
  • “抑制异常在这里意味着什么?”
    如果 cancel_me() 在捕获异常后不会重新引发异常。正如 cancelled() 的文档所述:“当使用 cancel() 请求取消并且包装的协程传播抛出的 CancelledError 异常时,任务将被取消。” https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancelled

关于Python Asyncio 任务取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56052748/

相关文章:

javascript - 如何轻松处理javascript异步函数中的所有错误?

python - 获取符合某些条件的 Pandas DataFrame 的列和行索引对

asynchronous - 服务总线 - "The server did not provide a meaningful reply; this might be caused by a premature session shutdown"

python - 如何为许多子图制作一个图例?

python - 如何同时检查输入是否为数字和范围? Python

python - 如何显示日期选择器小部件?

python - 列表子列表的优化

c# - MVVM 中的后台加载和构造函数注入(inject)

python - 将一分钟的分钟数转换为小时数和分钟数python

python - 如何重命名 conda 环境?