Как я могу спать() параллельно внутри задачи asyncio, если родительская функция не асинхронна?

#python-3.x #multithreading #python-asyncio #sleep

Вопрос:

код:

 class App:
    def __init__(self):
        # some of the code
        ...
        ...
        xxx.add_handler(self.event_handler, event_xyz)
        asyncio.create_task(self.keep_alive())
        xxx.run_until_disconnected()

    def keep_alive(self):
        # stuff to keep connection alive
        ...
        ...
        time.sleep(5) # this will block whole script
        asyncio.sleep(5) # this won't work because of lack of async on _init_ and keep_alive
    
    async def event_handler(self):
        await stuff
    
    # other functions

if __name__ == '__main__':
    App()
 

Та часть кода, которая поддерживает соединение, имеет ограничения api. Итак, мне нужно, чтобы sleep оператор был внутри keep_alive() функции.

Я понимаю, что дизайн кода можно полностью изменить, чтобы он работал, но это большой скрипт, и все остальное работает идеально. Итак, предпочтительнее, если бы это можно было заставить работать. Я открыт для использования чего-либо еще, например потоков, до тех пор, пока остальная часть кода не блокируется во время sleep .

Комментарии:

1. Есть ли у вас в коде цикл событий ansycio вообще, или это будет единственный асинхронный материал, который вам понадобится?

2. @Blckknght обновил код с помощью части event_handler, которая является асинхронной функцией.

Ответ №1:

Это простая ситуация. time.sleep заблокирует текущий поток, включая цикл событий asyncio для этого потока (если он есть). Период. Дело закрыто.

Если ваш API требует, чтобы у вас были вызовы time.sleep, и ваша программа должна что-то делать, пока текущий поток спит, то asyncio не является решением. Это не означает, что asyncio нельзя использовать для других потоков или других целей в рамках разработки вашей программы, но он абсолютно не может выполнять другие задачи в текущем потоке в течение интервала времени.сна.

Что касается функции keep_alive в вашем фрагменте кода: эта функция не может быть превращена в задачу, поскольку она не объявлена как «асинхронный деф». Вызов asyncio.sleep() изнутри этого типа регулярной функции является ошибкой; он всегда должен быть «ожидаемым», и ключевое слово «await» должно находиться внутри асинхронной функции def. С другой стороны, вызов time.sleep внутри асинхронной функции def не является ошибкой, и функция будет работать должным образом. Но это, вероятно, не то, чем ты хочешь заниматься.