Python asyncio有一个特殊的设计选择,这会导致一个问题,很可能就是您遇到的问题:
使用创建的任务
.create_task
不会被事件循环硬引用。(它只保留了对它们的微弱引用)。虽然这有时不会出现在简单的运行中,或者当任务很少时——因为弱引用的任务实际上是在异步循环核心的第一次执行中开始的,当有很多任务(在我进行的一些测试中大约有2000个)时,或者可能更少,当任务创建在多个地方时,比如在这段代码中,任务可能会消失得无影无踪。
这很可能是您的问题,解决方案只是保留对由创建的任务的引用
.create_task
调用-一个简单的类级别
set
可以保留这些(或实例级别,如果您有
__init__
方法):
...
class IterableAgent(BaseModel):
queue: asyncio.Queue | None = None
done: bool = False
timeout: int = 10
running_tasks: set[asyncio.Task] = set()
...
def __aiter__(self):
self.done = False
self.queue = asyncio.Queue()
task = asyncio.create_task(self.run())
self.running_tasks.add(task)
task.add_done_callback(self.running_tasks.discard)
return self
...
(当然,如果有其他调用,请使用相同的模式
.create_task
)。
至于是否记录了这种行为,请注意“重要”注释:
https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task