Задания Asyncio останавливаются на ожидании - PullRequest
0 голосов
/ 14 января 2020

у меня есть одна функция asyn c, в которой мало кто ждет

async def registerit(arg1,arg2):
    async with aiohttp.ClientSession() as session:
        url="https://google.com"
        headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
        response = await session.get(url, headers=headers)

код останавливается на ожидании, по какой-то причине он только случается, если я использую

task = asyncio.create_task(registerit(arg1,arg2))
tasks.append(task)

Функция работает нормально, если я использую

await registerit(arg1,arg0)

Спасибо за вашу помощь.

1 Ответ

3 голосов
/ 14 января 2020

Я не вижу подробностей того, как вы в действительности выполняете код, но я предполагаю, что вы не даете своей задаче (с asyncio.create_task) свой ход для выполнения.

await registerit(arg1,arg0) работает, потому что когда вы используете await, вы переключаете текущий контекст выполнения на другую сопрограмму, которая может просто оказаться той, которую вы только что инициировали с await. Await создает эту новую сопрограмму и ожидает ее завершения sh и получает ее вывод.

В отличие от await, задачи предназначены для параллельной (фоновой) работы. Помните, что когда вы создаете его, вы просто помещаете его в очередь сопрограмм для выполнения в точке переключения контекста. Так что если вы запустите create_task в качестве последней строки кода , то сопрограмма с работой будет создана и помещена в очередь выполнения, но очередь просто остановится там вместе с программой.

Но если бы вы вернули управление программой обратно событию l oop с помощью await и , остановившим конец программы с помощью чего-то вроде await asyncio.sleep(5), вы бы получили "не "рабочий" код работает . Или вы можете просто запустить l oop с run_forever().

Вы можете увидеть это, запустив мой test.py:

# test.py
# python 3.8.1

import asyncio
import aiohttp


async def non_working_solution():
    task = asyncio.create_task(registerit())


async def working_solution():
    await registerit()


async def registerit():
    async with aiohttp.ClientSession() as session:
        url="https://google.com"
        headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
        response = await session.get(url, headers=headers)
        print(response)


async def main():
    print('Running working solution')
    await working_solution()
    print('Running NON-working solution')
    await non_working_solution()

    # THE FIX
    # =======
    time_to_sleep = 5
    print('Waiting for', time_to_sleep, 'seconds for the output of the non-working solution')
    await asyncio.sleep(time_to_sleep)
    # =======


if __name__ == '__main__':
    asyncio.run(main())
...