例外线程“MainThread"中没有当前事件循环在运行新循环时 [英] Exception " There is no current event loop in thread 'MainThread' " while running over new loop
问题描述
这是简单的测试代码和结果.
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'.
我在 new loop
上运行 async def test()
并期望 asyncio.sleep(1)
由 test()
也使用 new loop
.
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
.
与此相反,sleep()
似乎仍然访问 main loop
我设置为 None
.
In contrast to that, sleep()
still seems to access main loop
I set as None
.
我知道我可以在调用 之前使用
它将毫无例外地工作.asyncio.set_event_loop(loop)
将 main loop
重新设置为 new loop
run_until_complete()
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.
但是,我想知道对于 asyncio
来说,main loop
必须设置并用于协程是正常的,而不管运行协程的循环如何.
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.
推荐答案
我想知道对于
asyncio
来说,必须设置主循环并用于协程是正常的,而不管运行哪个协程的循环.
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()
来安排一个唤醒电话来完成未来.
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.
从 Python 3.6(或 3.5.3,包括对问题的修复)开始,当从由事件循环驱动的协程调用 get_event_loop()
时,它总是返回驱动它的事件循环.因此,您的代码可以正常工作.
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:
当从协程或回调(例如使用 call_soon
或类似 API 调度)调用时,此函数将始终返回正在运行的事件循环.
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.
这篇关于例外线程“MainThread"中没有当前事件循环在运行新循环时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!