简体   繁体   English

Python 异步任务取消

[英]Python Asyncio Task Cancellation

I was reading asyncio documentation for task cancel and I came across this -我正在阅读任务取消的异步文档,我遇到了这个-

To cancel a running Task use the cancel() method.要取消正在运行的任务,请使用 cancel() 方法。 Calling it will cause the Task to throw a CancelledError exception into the wrapped coroutine.调用它将导致 Task 将 CancelledError 异常抛出到包装的协程中。 If a coroutine is awaiting on a Future object during cancellation, the Future object will be cancelled.如果协程在取消期间正在等待 Future object,则 Future object 将被取消。

cancelled() can be used to check if the Task was cancelled. cancelled() 可用于检查任务是否被取消。 The method returns True if the wrapped coroutine did not suppress the CancelledError exception and was actually cancelled.如果包装的协程没有抑制 CancelledError 异常并且实际上已被取消,则该方法返回 True。

I have a few questions here -我在这里有几个问题-

  • Is wrapped coroutine the coroutine in which cancel is called?包裹协程是调用取消的协程吗? Let's take an example here -我们在这里举个例子——

     async def wrapped_coroutine(): for task in asyncio.Task.all_tasks(): task.cancel()

    So wrapped_coroutine() is the wrapped coroutine where task will throw an exception?那么wrapped_coroutine()是任务会抛出异常的封装协程吗?

  • When will this exception be thrown?什么时候会抛出这个异常? And where?在哪里?

  • What does suppress the exception mean here?在这里抑制异常是什么意思? Does it mean this -是不是这个意思——

     async def wrapped_coroutine(): for task in asyncio.Task.all_tasks(): task.cancel() try: await task except asyncio.CancelledError: print("Task cancelled")

    If not, please provide an example on how to suppress this exception.如果不是,请提供有关如何抑制此异常的示例。

And an unrelated(it's related to cancelling tasks), how do I retrieve exceptions out of these tasks when I'm cancelling these so I don't see this -还有一个不相关的(它与取消任务有关),当我取消这些任务时如何从这些任务中检索异常,所以我看不到这个 -

Task exception was never retrieved future:

Is it before task.cancel() or in try before await task (in the above example)?是在task.cancel()之前还是在await task之前try (在上面的示例中)?

Looking at the code in the example given in the documentation https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel :查看文档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())

Answering your questions:回答您的问题:

  • "Is the wrapped coroutine the coroutine in which cancel is called?" “被包装的协程是调用取消的协程吗?”
    No, the wrapped coroutine here is cancel_me() ;不,这里包装的协程是cancel_me() .cancel() is called in main() . .cancel()main()中调用。
  • "When will this exception be thrown? And where?" “什么时候会抛出这个异常?在哪里?”
    This exception is thrown after task.cancel() is called.调用task.cancel()后会引发此异常。 It is thrown inside the coroutine, where it is caught in the example, and it is then re-raised to be thrown and caught in the awaiting routine.它被抛出到协程中,在示例中被捕获,然后被重新引发以被抛出并在等待的例程中捕获。
  • "What does suppress the exception mean here?" “这里压制异常是什么意思?”
    If cancel_me() would not have re-raised the exception after catching it.如果cancel_me()在捕获异常后不会重新引发异常。 As the documentation of cancelled() states: "The Task is cancelled when the cancellation was requested with cancel() and the wrapped coroutine propagated the CancelledError exception thrown into it."正如cancelled()的文档所述:“当使用 cancel() 请求取消并且包装的协程传播了抛出的 CancelledError 异常时,任务被取消。” https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancelled https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancelled

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM