python
runtime_error
ai_generated
true
asyncio.exceptions.CancelledError:任务被销毁但仍在等待中!
asyncio.exceptions.CancelledError: Task was destroyed but it is pending!
ID: python/asyncio-gather-cancelled-error
80%修复率
85%置信度
0证据数
2024-03-15首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.8 | active | — | — | — |
| 3.9 | active | — | — | — |
| 3.10 | active | — | — | — |
根因分析
使用 asyncio.gather() 且 return_exceptions=False 时,如果某个任务因超时等原因抛出 CancelledError,gather 被取消,其他任务未被正确等待,导致待处理任务销毁警告。
English
When using asyncio.gather() with return_exceptions=False, if one task raises CancelledError (e.g., due to timeout), the gather is cancelled and other tasks are not properly awaited, leading to pending task destruction warnings.
解决方案
-
90% 成功率
results = await asyncio.gather(*tasks, return_exceptions=True) for r in results: if isinstance(r, asyncio.CancelledError): # handle cancellation gracefully -
85% 成功率
done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION) for task in pending: task.cancel() await asyncio.gather(*pending, return_exceptions=True)
无效尝试
常见但无效的做法:
-
60% 失败
CancelledError is not always raised synchronously; it can be raised during await, and ignoring it may leave tasks in inconsistent states.
-
70% 失败
Shield only protects against cancellation of the outer task, not the inner tasks; it doesn't solve the root issue of pending tasks.