The is the simple test code and the result.
import asyncio
async def test():
await asyncio.sleep(1)
if __name__ == '__main__':
asyncio.set_event_loop(None) # Clear the main loop.
loop = asyncio.new_event_loop() # Create a new loop.
loop.run_until_complete(test()) # Run coroutine over the new loop
Traceback (most recent call last):
File "test_test.py", line 11, in <module>
loop.run_until_complete(test())
File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete
return future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "test_test.py", line 5, in test
await asyncio.sleep(1)
File "/usr/lib/python3.5/asyncio/tasks.py", line 510, in sleep
loop = events.get_event_loop()
File "/usr/lib/python3.5/asyncio/events.py", line 632, in get_event_loop
return get_event_loop_policy().get_event_loop()
File "/usr/lib/python3.5/asyncio/events.py", line 578, in get_event_loop
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'MainThread'.
I run the async def test()
over the new loop
and expected that asyncio.sleep(1)
which is nested by test()
also use the new loop
.
In contrast to that, sleep()
still seems to access main loop
I set as None
.
I know I can re-set a main loop
as the new loop
with asyncio.set_event_loop(loop)
before calling run_until_complete()
and it will work with no exception.
However, I want to know it is normal for asyncio
that main loop
Must be set and is used for coroutines regardless of a loop over which coroutine is run.
In case that doesn’t work, it will generate a new event loop for the current thread using and then returns this event loop. Note that while this works well for generating the event loop, but depending on the way you use the event loop, you might encounter further error messages like
In contrast to that, sleep () still seems to access main loop I set as None. I know I can re-set a main loop as the new loop with asyncio.set_event_loop (loop) before calling run_until_complete () and it will work with no exception.
As of Python 3.6 (or 3.5.3, which included a fix for the issue ), when get_event_loop () is invoked from a coroutine driven by an event loop, it always returns the event loop that drives it. As a result, your code works correctly.
How to loop the program after an exception is thrown in java? Read the inputs and perform the required calculations within a method. Keep the code that causes exception in try block and catch all the possible exceptions in catch block (s).
I want to know it is normal for
asyncio
that main loop Must be set and is used for coroutines regardless of a loop over which coroutine is run.
This used to be required prior to Python 3.6. The reason is that functions like asyncio.sleep()
need an event loop to be able to use loop.call_later()
to schedule a wake-up call to complete the future.
As of Python 3.6 (or 3.5.3, which included a fix for the issue), when get_event_loop()
is invoked from a coroutine driven by an event loop, it always returns the event loop that drives it. As a result, your code works correctly.
The new behavior is not mentioned in the online documentation, but is in the docstring:
When called from a coroutine or a callback (e.g. scheduled with
call_soon
or similar API), this function will always return the running event 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