RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop
RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop
我正在使用 Flask 在 python 中制作仪表板。
它需要 运行 三个任务: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)?
我试过切换它,使 flask 成为主线程,datastream_handler()
作为 threading.Thread 启动(使用 asyncio.run 从非线程启动异步函数-异步功能)。然而,这只是给出了同样的错误。
我查了一下这个错误,有几个人在使用 Django 和 requests-html 时遇到了同样的错误-html,但是他们的发现是针对他们各自的框架的,不能应用于 flask。
这是我的代码:
datastream_handler
和 dashboard_handler
在不同的文件中;
dashboard_handler
只是一个带 while 循环的普通同步函数,而 datastream_handler
是一个异步函数,目前仅包含一个带有 print 和 asyncio.sleep 的 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
应用应该在主线程中启动。
关于这个错误,
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
将其转换为线程异步,并且无法在线程中完成。
如果你想 运行 3 个并发使用线程,其中一个是 asynchronous
也许你可以使用 python-worker
link
- 将
datastream_handler
和 dashboard_handler
定义为工人
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
将自动 运行 作为一个线程。
我正在使用 Flask 在 python 中制作仪表板。
它需要 运行 三个任务: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)?
我试过切换它,使 flask 成为主线程,datastream_handler()
作为 threading.Thread 启动(使用 asyncio.run 从非线程启动异步函数-异步功能)。然而,这只是给出了同样的错误。
我查了一下这个错误,有几个人在使用 Django 和 requests-html 时遇到了同样的错误-html,但是他们的发现是针对他们各自的框架的,不能应用于 flask。
这是我的代码:
datastream_handler
和 dashboard_handler
在不同的文件中;
dashboard_handler
只是一个带 while 循环的普通同步函数,而 datastream_handler
是一个异步函数,目前仅包含一个带有 print 和 asyncio.sleep 的 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
应用应该在主线程中启动。
关于这个错误,
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
将其转换为线程异步,并且无法在线程中完成。
如果你想 运行 3 个并发使用线程,其中一个是 asynchronous
也许你可以使用 python-worker
link
- 将
datastream_handler
和dashboard_handler
定义为工人
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
将自动 运行 作为一个线程。