[英]RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop
I'm making a dashboard in python, using flask.我正在使用烧瓶在 python 中制作仪表板。 It needs to run three tasks: flask, datastream_handler()
, and dashboard_handler()
.它需要运行三个任务:flask、 datastream_handler()
和dashboard_handler()
。 One of these tasks, datastream_handler()
, is required to be an async function.其中一项任务datastream_handler()
需要是异步函数。
I've used threading to allow the tasks to run at the same time, (flask and dashboard_handler()
are threads, datastream_handler()
is run from the main thread).我使用线程来允许任务同时运行,(flask 和dashboard_handler()
是线程, datastream_handler()
从主线程运行)。
dashboard_handler()
and datastream_handler()
start up and run perfectly, and flask appears to start but when I visit the webpage it gives me an error in terminal: RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
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.
I'm confused, because I have awaited the async function (datastream_handler) directly?我很困惑,因为我直接等待异步函数(datastream_handler)?
I've tried switching it around so that flask is the main thread, and datastream_handler()
is started as a threading.Thread (using asyncio.run to start the async function from a non-async function).我尝试过切换它,以便 flask 是主线程,并且datastream_handler()
作为 threading.Thread 启动(使用 asyncio.run 从非异步函数启动异步函数)。 However, this just gave the same error.但是,这只是给出了同样的错误。
I looked up this error and a couple of people had the same error with Django and requests-html, but their findings were specific to their respective framework and couldn't be applied to flask.我查了这个错误,有几个人在使用 Django 和 requests-html 时遇到了同样的错误,但他们的发现是针对他们各自的框架的,不能应用于烧瓶。
Here is my code:这是我的代码:
datastream_handler
and dashboard_handler
are in different files; datastream_handler
和dashboard_handler
在不同的文件中; dashboard_handler
is just a normal synchronous function with a while loop and datastream_handler
is an async function which currently only contains a while loop with print and asyncio.sleep, for testing purposes. dashboard_handler
只是一个带有 while 循环的普通同步函数,而datastream_handler
是一个异步函数,目前只包含一个带有 print 和 asyncio.sleep 的 while 循环,用于测试目的。
I don't think the contents of these functions are causing the errors, but correct me if I am wrong我不认为这些函数的内容导致错误,但如果我错了,请纠正我
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())
If anyone can help I would be very grateful如果有人可以提供帮助,我将不胜感激
Thanks谢谢
What is the reason putting Flask
in thread?将Flask
放入线程的原因是什么? Flask
app should be initiated in the main thread. Flask
应用程序应该在主线程中启动。
About this error, RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
关于这个错误, RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
I think this come from 2 reasons:我认为这来自两个原因:
async def index()
which flask will turn it into threaded async using asgiref
's module AsyncToSync
and at it can't be done in thread.您正在使用async def index()
哪个烧瓶将使用asgiref
的模块AsyncToSync
将其转换为线程异步,并且无法在线程中完成。 If you want to run 3 of those concurrently using thread and one of it is asynchronous
maybe you can use python-worker
link如果您想使用线程同时运行其中的 3 个并且其中一个是asynchronous
的,那么您可以使用python-worker
链接
datastream_handler
and dashboard_handler
as a worker将datastream_handler
和dashboard_handler
定义为 workerfrom 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
and dashboard_handler
will automatically run as a thread. datastream_handler
和dashboard_handler
将自动作为线程运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.