Запустите асинхронную функцию из функции синхронизации в уже запущенном цикле событий.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Запустите асинхронную функцию из функции синхронизации в уже запущенном цикле событий.

Сообщение Anonymous »

В моем приложении Python у меня есть функция синхронизации boo(), которая вызывается внутри цикла выполнения событий. boo() должен получить некоторые данные из foo(arg1, arg2), которая является async функцией.
К сожалению, Я не могу превратить boo() в асинхронную функцию. Он должен оставаться синхронизированным. (Это ограничение не в моих руках).
Как мне вызвать foo(arg1, arg2) из boo(), дождаться завершения, и продолжить выполнение?
Минимальный воспроизводимый пример
Я попытался создать минимальный воспроизводимый пример. Это самое близкое, что я мог получить. Реальное приложение большое и сложное и может вести себя по-разному.

Код: Выделить всё

import time
import asyncio

async def work_for_data():
time.sleep(3)
return 42

# sync function, calling async function
def get_number():
return asyncio.get_event_loop().run_until_complete(work_for_data())

async def get_data():
return get_number()

async def run():
loop = asyncio.get_event_loop()
task = asyncio.create_task(get_data())
loop.run_until_complete(task)

if __name__ == "__main__":
asyncio.run(run())
Этот код вызывает:

Код: Выделить всё

  File "./minimal_example.py", line 9, in get_number
return asyncio.get_event_loop().run_until_complete(work_for_data())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/Cellar/[email protected]/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 629, in run_until_complete
self._check_running()
File "/usr/local/Cellar/[email protected]/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 588, in _check_running
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
Попытки решить проблему
Я предпринял много попыток решить ее, но все они не сработали.Попытка 1

Код: Выделить всё

data = asyncio.run(foo(arg1, arg2))
Вызвало следующее исключение:

Код: Выделить всё

    data = asyncio.run(foo(arg1, arg2))
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/.pycharm_helpers/pydevd_asyncio/pydevd_nest_asyncio.py", line 143, in run
loop.run_until_complete(task)
File "uvloop/loop.pyx", line 1511, in uvloop.loop.Loop.run_until_complete
File "uvloop/loop.pyx", line 1504, in uvloop.loop.Loop.run_until_complete
File "uvloop/loop.pyx", line 1377, in uvloop.loop.Loop.run_forever
File "uvloop/loop.pyx", line 518, in uvloop.loop.Loop._run
RuntimeError: this event loop is already running.
Попытка 2

Код: Выделить всё

loop = asyncio.get_event_loop()
data = loop.run_until_complete(foo(arg1, arg2))
Вызвало следующее исключение:

Код: Выделить всё

    data = loop.run_until_complete(foo(arg1, arg2))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "uvloop/loop.pyx", line 1511, in uvloop.loop.Loop.run_until_complete
File "uvloop/loop.pyx", line 1504, in uvloop.loop.Loop.run_until_complete
File "uvloop/loop.pyx", line 1377, in uvloop.loop.Loop.run_forever
File "uvloop/loop.pyx", line 518, in uvloop.loop.Loop._run
RuntimeError: this event loop is already running.
Попытка 3

Код: Выделить всё

loop = asyncio.get_running_loop()
with ThreadPoolExecutor() as executor:
future = executor.submit(lambda: asyncio.run_coroutine_threadsafe(foo(arg1, arg2), loop).result())
data = future.result()
Интерпретатор завис при выполнении Future.result()
Попытка 4

Код: Выделить всё

    loop = asyncio.get_event_loop()
future = asyncio.Future()

def callback(task):
if task.exception():
future.set_exception(task.exception())
else:
future.set_result(task.result())

task = asyncio.run_coroutine_threadsafe(foo(arg1, arg2), loop)
task.add_done_callback(callback)

result = task.result()  ## Stuck here
return result
Интерпретатор зависал при выполнении Task.result()

Подробнее здесь: https://stackoverflow.com/questions/788 ... event-loop
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»