异常“线程 'MainThread' 中没有当前事件循环”,而新循环 运行
Exception " There is no current event loop in thread 'MainThread' " while running over new loop
这是简单的测试代码和结果。
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'.
我 运行 async def test()
在 new loop
之上,并期望由 test()
嵌套的 asyncio.sleep(1)
也使用 new loop
。
与此相反,sleep()
似乎仍然可以访问 main loop
我设置为 None
。
我知道我可以在调用 run_until_complete()
之前用 asyncio.set_event_loop(loop)
将 main loop
重新设置为 new loop
并且它将毫无例外地工作。
但是,我想知道 asyncio
必须设置 main loop
并且用于协程是正常的,而不管协程是 运行 的循环。
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.
这在 Python 3.6 之前是必需的。原因是像asyncio.sleep()
这样的函数需要一个事件循环才能使用loop.call_later()
来安排唤醒调用来完成未来。
从 Python 3.6(或 3.5.3,其中包含对 the issue 的修复)开始,当从事件循环驱动的协程调用 get_event_loop()
时,它总是returns 驱动它的事件循环。因此,您的代码可以正常工作。
联机文档中未提及新行为,但在 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.
这是简单的测试代码和结果。
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'.
我 运行 async def test()
在 new loop
之上,并期望由 test()
嵌套的 asyncio.sleep(1)
也使用 new loop
。
与此相反,sleep()
似乎仍然可以访问 main loop
我设置为 None
。
我知道我可以在调用 run_until_complete()
之前用 asyncio.set_event_loop(loop)
将 main loop
重新设置为 new loop
并且它将毫无例外地工作。
但是,我想知道 asyncio
必须设置 main loop
并且用于协程是正常的,而不管协程是 运行 的循环。
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.
这在 Python 3.6 之前是必需的。原因是像asyncio.sleep()
这样的函数需要一个事件循环才能使用loop.call_later()
来安排唤醒调用来完成未来。
从 Python 3.6(或 3.5.3,其中包含对 the issue 的修复)开始,当从事件循环驱动的协程调用 get_event_loop()
时,它总是returns 驱动它的事件循环。因此,您的代码可以正常工作。
联机文档中未提及新行为,但在 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.