【问题标题】:How to treat and deal with event loops?如何对待和处理事件循环?
【发布时间】:2017-03-06 12:46:33
【问题描述】:

在以下代码中返回异步值之前是否需要loop.close()

import asyncio

async def request_url(url):
    return url

def fetch_urls(x):
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x]))

也就是说,fetch_urls 应该变成这样吗?:

def fetch_urls(x):
    loop = asyncio.get_event_loop()
    results = loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x]))
    loop.close()
    return results

如果需要loop.close(),那么如何在不引发异常的情况下再次调用fetch_urlsRuntimeError: Event loop is closed

previous post 指出关闭循环并开始新循环是一种很好的做法,但它没有指定如何打开新循环?

【问题讨论】:

  • 为了完整起见,您可以通过调用 asyncio.new_event_loop() 来启动新的事件循环。

标签: cpython


【解决方案1】:

您还可以多次使用run_until_complete 来保持事件循环处于活动状态,并在程序结束时将其关闭:

import asyncio


async def request_url(url):
    return url


def fetch_urls(loop, urls):
    tasks = [request_url(url) for url in urls]
    return loop.run_until_complete(asyncio.gather(*tasks, loop=loop))


loop = asyncio.get_event_loop()
try:
    print(fetch_urls(loop, ['a1', 'a2', 'a3']))
    print(fetch_urls(loop, ['b1', 'b2', 'b3']))
    print(fetch_urls(loop, ['c1', 'c2', 'c3']))
finally:
    loop.close()

【讨论】:

  • 谢谢,这是一个很好的例子:)
【解决方案2】:

不,异步函数(在这种情况下为request)不应该关闭事件循环。命令loop.run_until_completeclose在事件循环用完后立即停止。

fetch_urls应该是第二个版本——也就是说,它会得到一个事件循环,运行这个事件循环直到没有什么可做的,然后关闭它loop.close()

【讨论】:

  • run_until_complete() stop()s 循环,它不会关闭它。
  • @Udi:谢谢,已修复。
  • @Dave:请检查更新;我之前错了。
猜你喜欢
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多