如何使用Asyncio并发运行Dash(Flask)服务与自定义协程
Dash 与 Asyncio 协程并发实现
当前实现的核心卡点:Dash 基于 Flask 提供的
run_server是同步阻塞式的WSGI服务,哪怕把它包装成async异步函数,代码执行到这行时会直接接管整个线程,完全不会把控制权交还给asyncio事件循环,自然会卡死所有其他协程的执行。
不需要从零改造Dash本身,以下两种可落地的方案都能实现main业务协程和Dash服务的并发运行:
方案1:Dash服务跑在独立工作线程(改造成本最低,稳定性最高)
这是生产环境最常用的适配方式,不需要修改Dash本身的任何代码,利用asyncio自带的线程池接口把同步服务和主事件循环解耦:
- 把原来的
async def run_dashboard()改回普通同步函数,因为它会运行在独立线程,不需要被asyncio调度 - 用
asyncio.to_thread把Dash服务的启动逻辑丢到独立线程运行,这部分逻辑完全不会阻塞主事件循环 - 用
asyncio.gather同时启动Dash线程任务和main业务协程
适配后的代码示例:
import asyncio # 原有业务逻辑完全保留 async def main(): # 原有代码不变 while True: try: await client.handle_message() except ConnectionClosedError as error: logger.error(error) for strategy in strategies: await asyncio.create_task(...) # 改成同步函数,适配线程运行 def run_dashboard(): app = create_app() # 必须关闭use_reloader,否则Flask的重载机制会启动子进程,和线程模型冲突 app.run_server('0.0.0.0', 5000, debug=False, use_reloader=False) if __name__ == '__main__': # 原有初始化代码不变 async def run_all(): # 并发启动Dash线程和主业务协程 await asyncio.gather( asyncio.to_thread(run_dashboard), main() ) asyncio.run(run_all())
这个方案的优势:
- 同进程内的内存数据完全共享,Dash的回调可以直接读取main协程里采集、计算的所有数据,不需要额外的跨进程通信
- 完全兼容已写好的Dash布局、回调代码,不需要做异步改造
- 独立线程的服务异常不会直接拖垮主业务协程,稳定性更好
方案2:Dash服务适配为ASGI异步服务(完全融入asyncio生态)
如果你不想引入独立线程,想让所有任务都跑在同一个asyncio事件循环里,可以把同步的Flask/Dash应用通过适配器转成异步ASGI应用,配合uvicorn启动。
需要额外安装asgiref、uvicorn两个依赖,之后修改run_dashboard为真正的异步协程:
from asgiref.wsgi import WsgiToAsgi import uvicorn async def run_dashboard(): app = create_app() # 把同步WSGI的Dash应用转换为ASGI异步应用 asgi_app = WsgiToAsgi(app.server) server = uvicorn.Server( uvicorn.Config( app=asgi_app, host="0.0.0.0", port=5000, log_level="info" ) ) # 异步启动服务,控制权会正常交回事件循环 await server.serve()
这种方式下,入口代码可以直接通过gather并发启动两个协程,不需要独立线程:
if __name__ == '__main__': asyncio.run( asyncio.gather( run_dashboard(), main() ) )
常见踩坑提示
- 不要直接把
app.run_server放在async函数里调用:哪怕你给函数加了async标识,内部的同步阻塞逻辑依然会锁死整个事件循环,其他协程根本得不到执行机会 - 如果需要在Dash的回调里触发主业务的异步任务,不要在Dash回调里直接调用
asyncio.run(),需要提前把主事件循环的引用存为全局变量,通过asyncio.run_coroutine_threadsafe把任务安全投递回主循环执行,避免跨线程调用报错
内容的提问来源于stack exchange,提问作者orie
相关产品推荐
相关产品推荐

