在这里抑制`asyncio.CancelledError` 是否可以接受?

问题描述

示例:

    with suppress(asyncio.CancelledError):
        [await t for t in asyncio.all_tasks(loop=self.loop)
            if t is not asyncio.current_task()]

为了避免 Task was destroyed but it is pending! 警告,我必须在取消后等待任务,但等待它们会导致终端收到 CancelledError垃圾邮件。我知道它被取消了,但我不需要看到那个。

在此处使用 contextlib.suppress 是否会对取消产生负面影响?我可以避免看到取消的错误(或没有等待的任务已销毁警告)的唯一其他方法是使用 asyncio.wait 而不是 asyncio.gather 开始我的初始任务。出于某种原因,wait 似乎抑制了异常。我在 return_when=asyncio.FirsT_EXCEPTION 上使用 wait,在 return_exceptions=True 上使用 gather。但似乎无论我如何设置他们的关键字参数gather 都会打印异常,而 wait 不会。

解决方法

CancelledError 在 asyncio 中用于两个目的:一个是发出取消信号 request - 这是你在协程中被取消的那个 - 另一个是发出取消信号响应 - 这是您在等待任务的协程中得到的响应。抑制取消请求是一个坏主意,因为它会使协程不响应取消,从而导致以后出现问题。但是抑制响应完全没问题,因为您可能希望等待取消的协程(例如避免此警告)而不传播异常。

请注意,您的做法看起来不太正确,因为列表解析将在 first CancelledError 处终止,因此您无需等待其他协程。正确的方法是将 suppress 放入循环中,例如:

for t in tasks:
    with contextlib.suppress(asyncio.CancelledError):
        await t

# or,simpler:
await asyncio.gather(*tasks,return_exceptions=True)

wait() 不会传播异常,因为它返回 期货 的集合而不是它们的结果。如果您尝试访问返回的期货的结果,则会收到异常。 gather(return_exceptions=True) 返回结果和异常的混合,它不应该引发任何事情。如果是,请编辑问题以提供最小示例。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...