在Python3.6.1中调用loop.close asyncio.get_event_loop后无法创建新的事件循环

问题描述:

在从asyncio.get_event_loop()获取的循环上调用loop.close()之后的Python3.6.1中,可以创建新的循环?在Python3.6.1中调用loop.close asyncio.get_event_loop后无法创建新的事件循环

我已经看过其他帖子,正确地关闭一个循环的答案,以及如何使用task.cancel(),但一直没有能够使用任何这样的例子,让一个新的循环在第一次关闭后创建。我也尝试过明确地设置执行程序,然后调用executor.shutdown(wait = True),但这没有帮助。我也尝试了'del循环',并删除了一堆其他的东西。

文档指出关闭一个事件循环是幂等和不可逆的。这是否也意味着无法创建新的循环?

下面是一些简单的示例代码来说明这个问题: ``

#!/usr/bin/env python3.6 
''' 
To demonstrate an issue, the following code was adapted from: 
https://docs.python.org/3/library/asyncio-eventloop.html 
''' 
import asyncio 

def hello_world(loop): 
    print('Hello World') 
    loop.stop() 

loop = asyncio.get_event_loop() 
loop.call_soon(hello_world, loop) 
loop.run_forever() 
# loop.close() 


''' 
If the commented out loop.close() above is uncommented, 
the following code will fail with: 
    Traceback (most recent call last): 
     File "./aquestion.py", line 28, in <module> 
      loopNew.call_soon(hello_world, loopNew) 
     File "/Library/Frameworks/Python.framework/Versions/3.6/lib /python3.6/asyncio/base_events.py", line 573, in call_soon 
     self._check_closed() 
     File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed 
      raise RuntimeError('Event loop is closed') 
    RuntimeError: Event loop is closed 

''' 
loopNew = asyncio.get_event_loop() 
loopNew.call_soon(hello_world, loopNew) 
loopNew.run_forever() 

回答我的问题的任何尝试,将不胜感激。

或者,创建一个事件循环,将其用于各种用途,然后在长时间运行的程序即将退出时关闭该循环会是一种糟糕的形式吗?这似乎是错误的。

asyncio.get_event_loop返回当前循环。它不关注循环的状态。如果您在关闭一个循环后需要一个新循环,则可以使用asyncio.new_event_loop

请注意,获取新循环不会影响后续调用get_event_loop。如果您希望返回新的循环而不是原来的循环(特别是因为您可能已关闭它),则需要自行拨打asyncio.set_event_loop

import asyncio 

async def f(): 
    await asyncio.sleep(0) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(f()) 
loop.close() 

loop = asyncio.new_event_loop() 
asyncio.set_event_loop(loop) 
+0

非常感谢!这很好。 我以前尝试过new_event_loop,但是在那个实验中我必须做错了什么。 –

+0

我忽略提及'set_event_loop'。这可能与您遇到的问题有关。我已经更新了包含它的答案。 – dirn