asyncio.run() 给出 RuntimeError: Event loop is closed

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

我有以下代码,我正在尝试运行这些代码以使用 asyncio 和 aiohttp 异步从 api 获取数据:

import asyncio
import aiohttp

api = "...some api..."
apps = [
    ...list of api parameters...
]

def getTasks(sess):
    tasks = list()
    for app in apps:
        tasks.append(asyncio.create_task(sess.get(api+app, ssl = False)))
    return tasks

async def main():
    results = list()
    async with aiohttp.ClientSession() as atpSession:
        tasks = getTasks(atpSession)
        responses = await asyncio.gather(*tasks)
        for response in responses:
            results.append(await response.json())
    print(results[-1])
    print("Done!")

if __name__ == "__main__":
    asyncio.run(main())

虽然我正在获取响应数据,但是不断弹出以下错误:

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x000001C5D98F7490>
Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 116, in __del__
    self.close()
  File "C:\Program Files\Python310\lib\asyncio\proactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 750, in call_soon
    self._check_closed()
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

并且有多个这样的相似回溯一一显示。

现在我尝试的另一种方法是删除 asyncio.run(main()) 并只使用一些不同的代码行:

import asyncio
import aiohttp

api = "...some api..."
apps = [
    ...list of api parameters...
]

def getTasks(sess):
    tasks = list()
    for app in apps:
        tasks.append(asyncio.create_task(sess.get(api+app, ssl = False)))
    return tasks

async def main():
    results = list()
    async with aiohttp.ClientSession() as atpSession:
        tasks = getTasks(atpSession)
        responses = await asyncio.gather(*tasks)
        for response in responses:
            results.append(await response.json())
    print(results[-1])
    print("Done!")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

使用以下并没有给我之前的错误,而是给了我:

DeprecationWarning: There is no current event loop
  loop = aio.get_event_loop()

虽然,它确实给了我答案,但我的问题是,为什么会出现这些差异?作为 asyncio 的绝对初学者,我读到作为应用程序开发人员,我们应该使用像 asyncio.run() 这样的高级 api 而不是低级 api,那么为什么 asyncio.run() 会产生这样的问题?

python asynchronous concurrency python-asyncio aiohttp
1个回答
0
投票

您不需要

asyncio.create_task()
,这可能是错误的原因。看看this answer一个AsyncIO + AIOHTTP的工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.