asyncio.new_event_loop creates and returns a new event loop, exposing low-level controls such as run_until_complete. Run a coroutine, then close the loop in finally to release resources even when execution raises an exception. section 2.8.1
Manual coroutine execution
Create a loop, run main() until it finishes, and close the loop afterward. Unlike asyncio.run, this pattern does not cancel remaining tasks automatically, leaving room for special cleanup logic in finally. section 2.8.1
A separately created loop can also run forever inside a daemon thread. A Tkinter application can then remain responsive while submitting asynchronous work to that loop, a useful bridge for synchronous applications. section 7.4.2
Listing 2.21 Manually creating the event loop
import asyncio
async def main():
await asyncio.sleep(1)
loop = asyncio.new_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.close()
Runnable listing showing manual event-loop creation, coroutine execution, and guaranteed closure. section 2.8.1
