Python 3.7.4 和 3.10.6 asyncio 在 VS Code 调试调用堆栈中创建多个任务

问题描述 投票:0回答:2

在使用 asyncio 和 aiohttp 时,遇到了这个问题,想知道这是否仅限于 VSC 发生?

这个循环不断留下前一个循环的残留物。

while True:
     loop.run_until_complete(get_data())

它运行时没有任何剩余任务。

while True:
     asyncio.run(get_data())

session = aiohttp.ClientSession()

async def fetch(url, params=None):
     async with semaphore:
         async with session.get(url, params=params) as response:
             return await response.json()

我尝试将 while 循环移至被调用方法本身内,但结果仍然相同。还尝试使用信号量,但运气不佳。 我试图在单个循环中使用 aiohttp 管理多个rest api 调用方法,但发生这种情况,我猜我必须为每个 api 相关方法单独使用 asyncio.run 。那么现在避免这种情况的唯一方法就是不断关闭和重新打开单独的循环?这可能是 VSC 相关问题吗?


编辑:尝试使用 Python 3.10.6 和 VSCodium。我不知道是否是因为这里显示的是任务/循环而不是线程池,但没有复制相同的问题。将 Python 3.10.6 与 VS Code 结合使用时,增量问题仍然存在。那么这可能是 1) 怀疑是 VSC 问题还是 2) 只是两个 IDE 之间的调用堆栈处理方式不同?

while True:
     asyncio.run(get_data())

另一件事需要注意的是,使用 VSC 时,

ThreadPoolExecutor
堆叠会恰好停在第 20 个堆叠处:
ThreadPoolExecutor-0_19
。然后就不再有增量,也不再崩溃。

python rest visual-studio-code python-asyncio
2个回答
2
投票

注意:Python 3.7 已于 2023 年终止。如果最终出现这种情况,Python 和 VS Code 都不会对这样的旧版本进行修复。此外,

asyncio
在各个 Python 版本中经历了很多变化。


回答你的问题,

loop.run_until_complete
是一个低级事件循环函数。事件循环没有被清理,因为您也没有调用所需的低级循环管理函数,例如
loop.stop
loop.close
以及可能的其他函数。

asyncio.run
是一个高级函数,可以为您完成所有这些工作,这就是循环运行后被清理的原因。


它运行时没有任何剩余任务。

我认为这个评论在事件循环任务方面并不准确,因为任务具有特定的含义。看起来只是

ThreadPoolExecutors
被抛在了后面。事件循环不会在此执行器上运行,因此没有任务会运行。执行器用于诸如
asyncio.to_thread
loop.run_in_executor
之类的事情(不确定 Python 3.7 是否有其中任何一个)。它被抛在了后面,因为事件循环在启动时会创建一个。


0
投票

这有效。仍然不确定 VSC 和 VSCodium 与初始代码之间的不同结果,但尽管如此,对于其他偶然发现的人来说。

async def fetch(url, params=None):
     if not self.session:
         self.session = aiohttp.ClientSession()
     async with semaphore:
         async with session.get(url, params=params) as response:
             return await response.json()

async def get_data(self):
     json_response = await self.fetch("https://jsonplaceholder.typicode.com/todos/1")

while True:
     asyncio.run(get_data())
© www.soinside.com 2019 - 2024. All rights reserved.