0

我有同步的旧版 python 应用程序。我开始以这种方式(简化)在此应用程序中使用异步代码:


async def loader():
  async with trio.open_nursery() as nursery:
    # some async tasks started here
    await trio.to_thread.run_sync(legacyCode)
    

if __name__ == '__main__':
  trio.run(loader)

在里面legacyCode我可以使用trio.from_thread.run(asyncMethod)从遗留同步代码中运行一些异步代码。它运行良好,但现在我需要包含triopg内部使用的新库 () trio_asyncio

所以我需要修改启动应用程序的方式 - 我需要替换trio.runtrio_asyncio.run. 这很容易,但是在trio.to_thread->之后trio.from_thread,异步代码不起作用,因为 trio_asyncio 没有定义循环。

这是一个简短的演示:

import trio
import trio_asyncio

def main():
  trio.from_thread.run(amain)

async def amain():
  print(f"Loop in amain: {trio_asyncio.current_loop.get()}")  # this print none

async def loader():
  print(f"Loop in loader: {trio_asyncio.current_loop.get()}")  # this print some loop
  await trio.to_thread.run_sync(main)

if __name__ == '__main__':
  trio_asyncio.run(loader)

我应该如何修改上面的示例,以便 trio_asyncio 能够在amain()函数中找到循环?还是这种方法完全错误?trio如果是这样,当库需要使用和时,如何在大型同步应用程序中使用小块异步代码trio_asyncio

我使用python 3.9。

4

1 回答 1

0

最后我找到了解决方案......这似乎很容易:-)

trio_asyncio我们从线程中调用异步函数时,需要手动打开循环。所以唯一的区别是open_loop()在函数中添加调用amain()

import trio
import trio_asyncio


def main():
  trio.from_thread.run(amain)


async def amain():
  async with trio_asyncio.open_loop():
    print(f"Loop in amain: {trio_asyncio.current_loop.get()}")  # this print another loop


async def loader():
  print(f"Loop in loader: {trio_asyncio.current_loop.get()}")  # this print one loop
  await trio.to_thread.run_sync(main)


if __name__ == '__main__':
  trio_asyncio.run(loader)
于 2022-02-23T06:56:32.190 回答