我有一个像傻瓜一样的代码:
def render():
loop = asyncio.get_event_loop()
async def test():
await asyncio.sleep(2)
print("hi")
return 200
if loop.is_running():
result = asyncio.ensure_future(test())
else:
result = loop.run_until_complete(test())
当 loop
没有运行时很容易,只需使用 loop.run_until_complete
它返回 coro 结果,但如果循环已经在运行(我的阻塞代码在已经运行的应用程序中运行循环)我不能使用 loop.run_until_complete
因为它会引发异常;当我调用 asyncio.ensure_future
任务被安排并运行时,但我想在那里等待结果,有人知道该怎么做吗?文档不是很清楚如何执行此操作。
我尝试在 coro 中传递一个 concurrent.futures.Future
调用 set_result
然后调用 Future.result()
在我的阻塞代码上,但它没有阻止并且没有让其他任何东西运行。任何帮助,将不胜感激。
原文由 Ordani Sanchez 发布,翻译遵循 CC BY-SA 4.0 许可协议
要使用建议的设计实现
runner
,您需要一种方法从事件循环中运行的回调中单步执行事件循环。 Asyncio 明确禁止 递归事件循环,因此这种方法是死路一条。鉴于该约束,您有两个选择:
render()
本身成为协程;render()
(及其调用者)。假设#1 是不可能的,您可以实现
render()
的#2 变体,如下所示:请注意,您不能在
asyncio.get_event_loop()
render
因为没有(也不应该)为该线程设置事件循环。相反,生成运行器线程的代码必须调用asyncio.get_event_loop()
并将其发送到线程,或者将其保留在全局变量或共享结构中。