К сожалению, Я не могу превратить 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.
Код: Выделить всё
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.
Код: Выделить всё
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()
Попытка 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
Подробнее здесь: https://stackoverflow.com/questions/788 ... event-loop