lve*_*lla 11 python asynchronous python-3.x python-asyncio
从文档来看,启动异步应用程序的推荐方法似乎是使用asyncio.run(),所以我的应用程序如下所示:
async def async_main():
# Everything here can use asyncio.create_task():
o = ObjectThatMustBeKeptReferenced()
create_tasks_and_register_callbacks(o)
# Wait forever, ugly:
while True:
await asyncio.sleep(10000)
asyncio.run(async_main())
Run Code Online (Sandbox Code Playgroud)
最后的无限循环async_main()感觉非常错误。在其他语言中,我会永远调用事件循环。所以我尝试了这个:
def main():
loop = asyncio.get_event_loop()
# Everything here can use asyncio.create_task():
o = ObjectThatMustBeKeptReferenced()
create_tasks_and_register_callbacks(o)
# Wait forever, pretty:
loop.run_forever()
main()
Run Code Online (Sandbox Code Playgroud)
RuntimeError: no running event loop这里的问题是,当我在函数内部调用时asyncio.create_task(),即使事件循环是在线程上创建并注册的,这也会失败并出现各种错误。
什么是Pythonic,一种在asyncio事件循环中永远休眠的方法?
您可以简单地将sleep循环更改为从未设置的临时事件:
# wait forever
await asyncio.Event().wait()
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以轻松修改它以将事件存储到变量中并将其作为关闭信号传播。
另一种选择是让创建任务的函数返回它创建的任务,在这种情况下,您可以等待它们,即使(或正是因为)它们永远不会完成:
async def async_main():
o = ObjectThatMustBeKeptReferenced()
tasks = create_tasks_and_register_callbacks(o)
# wait forever, or until a task raises
await asyncio.gather(*tasks)
Run Code Online (Sandbox Code Playgroud)
asyncio.run(async_main())虽然这并不能清楚地传达永远循环的意图,但它的优点是,如果任何任务引发未处理的异常,它将停止程序(并将异常传播到调用的代码)。