Запуск нескольких асинхронных задач и ожидание их завершения в django,

#python #django #asynchronous #async-await #python-asyncio

#python #django #асинхронный #async-ожидание #python-asyncio

Вопрос:

У меня есть функция, которая

 
data=[]
async def connect(id):
    d= await database_sync_to_async(model.objects.filter())
    data.append(d)
 

и я вызываю функцию подключения, например

 
import asyncio
loop = asyncio.get_event_loop()
try:
    # run_forever() returns after calling loop.stop()
    tasks =[connect(1),connect(2),connect(3),connect(4),connect(5)]
    a, b = loop.run_until_complete(asyncio.gather(*tasks))
finally:
    loop.close()

 

Но это не работает, в нем говорится, что в потоке «Thread-3» нет текущего цикла событий.

Как я могу это реализовать?

Ответ №1:

Цитирование документа для asyncio.get_event_loop() :

Если в текущем потоке ОС не установлен текущий цикл событий, поток ОС является основным, а set_event_loop() еще не был вызван, asyncio создаст новый цикл событий и установит его как текущий.

Приложение Django обычно запускает несколько потоков, и в этом случае asyncio.get_event_loop() возникает исключение, которое вы получаете, когда вы не находитесь в основном потоке.

Возможна следующая возможность:

 import asyncio
try:
    loop = asyncio.get_event_loop()
except RuntimeError:
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
try:
    tasks =[connect(1),connect(2),connect(3),connect(4),connect(5)]
    results = loop.run_until_complete(asyncio.gather(*tasks))
finally:
    loop.close()
 

В зависимости от того, какую версию python вы используете (> = 3.7) и чего вы пытаетесь достичь, вы также можете использовать asyncio.run() .