In Python3.6.1 after calling loop.close() on a loop obtained from asyncio.get_event_loop(), can a new loop be created?
I've looked at other posts with answers for properly closing a loop, and also how to use task.cancel(), but have not been able to use any of those examples in a way that would let a new loop be created after the first was closed. I also tried explicitly setting executor and later calling executor.shutdown(wait=True), but that didn't help. I also tried 'del loop', and del a bunch of other things.
Documentation indicates that closing a an event loop is idempotent and irreversible. Does that also mean that a new loop cannot be created?
Here is some simple example code to demonstrate the issue:
`
#!/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()
`
Any attempts to answer my question would be appreciated.
Alternatively, would it be bad form to create an event loop, use it for a variety of purposes, and then just close that loop when the long running program is about to exit? This just seems wrong.
asyncio.get_event_loop
returns the current loop. It pays no attention to the state of the loop. If you need a new loop after closing one, you can use asyncio.new_event_loop
.
Be aware that getting a new loop won't affect subsequent calls to get_event_loop
. If you'd like that to return your new loop instead of the original one (especially since you've probably closed it), you'll need to call asyncio.set_event_loop
yourself.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With