[英]Django Channels Error: 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
我正在使用燒瓶在 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 時遇到了同樣的錯誤,但他們的發現是針對他們各自的框架的,不能應用於燒瓶。
這是我的代碼:
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.
我認為這來自兩個原因:
async def index()
哪個燒瓶將使用asgiref
的模塊AsyncToSync
將其轉換為線程異步,並且無法在線程中完成。 如果您想使用線程同時運行其中的 3 個並且其中一個是asynchronous
的,那么您可以使用python-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
和dashboard_handler
將自動作為線程運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.