例外线程“MainThread"中没有当前事件循环在运行新循环时 [英] Exception " There is no current event loop in thread 'MainThread' " while running over new loop

查看:92
本文介绍了例外线程“MainThread"中没有当前事件循环在运行新循环时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是简单的测试代码和结果.

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 looprun_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆