问题
我有一个目前不支持异步的库,需要从异步代码中调用。异步代码通过处理程序(以下代码中的handler
函数)调用库。执行处理程序时,库会定期调用回调(callback_wrapper
)以报告进度。
同步处理程序在ThreadPoolExecutor
中执行,以便主事件循环能够在处理程序运行时处理其他事件。
发生的事情是立即执行同步回调,但是异步回调仅在主处理程序执行后执行。理想的结果是立即执行异步回调。
我猜事件循环在run_in_executor
调用中被阻止,但是我不确定如何解决。
代码
import asyncio
import time
from concurrent.futures.thread import ThreadPoolExecutor
loop = asyncio.get_event_loop()
def handler():
print('handler started')
callback_wrapper()
time.sleep(1)
print('handler stopped')
async def callback():
print('callback')
def callback_wrapper():
print('callback wrapper started')
asyncio.ensure_future(callback(), loop=loop)
print('callback wrapper stopped')
async def main():
handler()
with ThreadPoolExecutor() as pool:
async def thread_handler():
await loop.run_in_executor(pool, handler)
loop.run_until_complete(main())
输出
handler started
callback wrapper started
callback wrapper stopped
handler stopped
callback
所需的输出
handler started
callback wrapper started
callback
callback wrapper stopped
handler stopped
答案 0 :(得分:1)
由于@ user4815162342的输入,我提出了以下解决方案:
import asyncio
import time
from concurrent.futures.thread import ThreadPoolExecutor
loop = asyncio.get_event_loop()
def handler():
print('handler started')
callback_wrapper()
time.sleep(1)
print('handler stopped')
async def callback():
print('callback')
def callback_wrapper():
print('callback wrapper started')
asyncio.run_coroutine_threadsafe(callback(), loop).result()
print('callback wrapper stopped')
async def main():
await thread_handler()
with ThreadPoolExecutor() as pool:
async def thread_handler():
await loop.run_in_executor(pool, handler)
loop.run_until_complete(main())
产生预期结果:
handler started
callback wrapper started
callback
callback wrapper stopped
handler stopped