我正在用python制作一个仪表板,使用flask。它需要运行三个任务:flask、datastream_handler()
和dashboard_handler()
。其中一个任务datastream_handler()
要求为异步函数。
我已经使用线程来允许任务同时运行,(flask和dashboard_handler()
是线程,datastream_handler()
是从主线程运行)。
dashboard_handler()
和datastream_handler()
启动并运行完美,flask似乎启动,但当我访问网页时,它在终端给我一个错误:RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
我很困惑,因为我直接等待异步函数(datastream_handler) ?
我试过切换它周围,使烧瓶是主线程,和datastream_handler()
开始作为一个线程。线程(使用asyncio.run从非async函数启动async函数)。然而,这只是给出相同的错误。
我查了一下这个错误,有几个人在Django和request -html中也有同样的错误,但是他们的发现是特定于他们各自的框架的,不能应用到flask。
下面是我的代码:datastream_handler
和dashboard_handler
在不同的文件中;dashboard_handler
只是一个带while循环的普通同步函数,datastream_handler
是一个async函数,目前只包含一个带print和asyncio的while循环。睡眠,用于测试目的。
我不认为这些函数的内容是导致错误,但纠正我,如果我错了
app = Flask(__name__)
socket = SocketIO(app)
@app.route("/")
async def index():
return render_template("index.html")
def start_flask():
socket.run(app, host="0.0.0.0", port=5000)
async def main():
q = Queue() #queue for data transfer
threading.Thread(target=dashboard_handler, args=(q,), daemon=True).start()
threading.Thread(target=start_flask, daemon=True).start()
await datastream_handler(q)
if __name__ == "__main__":
asyncio.run(main())
如果有人能帮助我,我将非常感激
感谢是什么原因把Flask
线程?Flask
app应该在主线程中启动。
关于这个错误,RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
我认为这有两个原因:
- 你在线程 中运行Flask
- 你正在使用
async def index()
哪个烧瓶将把它变成线程异步使用asgiref
的模块AsyncToSync
,在它不能在线程中完成。
如果你想同时运行三个线程,其中一个是asynchronous
,也许你可以使用python-worker
link
- 定义
datastream_handler
和dashboard_handler
作为worker
from worker import worker, async_worker
@async_worker
async def datastream_handler(q):
...
@worker
def dashboard_handler(q):
...
- 主文件:
if __name__ == "__main__":
q = Queue()
asyncio.run(datastream_handler(q))
dashboard_handler(q)
socket.run(app, host="0.0.0.0", port=5000)
datastream_handler
和dashboard_handler
将自动作为一个线程运行。