外部异步上下文管理器在内部异步生成器之前完成

特里克森

给出以下最小示例:

@asynccontextmanager
async def async_context():
    try:
        yield
    finally:
        await asyncio.sleep(1)
        print('finalize context')


async def async_gen():
    try:
        yield
    finally:
        await asyncio.sleep(2)
        # will never be called if timeout is larger than in async_context
        print('finalize gen')


async def main():
    async with async_context():
        async for _ in async_gen():
            break


if __name__ == "__main__":
    asyncio.run(main())

我正在break遍历异步生成器,并且希望在异步上下文管理器finally块运行之前完成finally块在此示例中,"finalize gen"将永远不会打印,因为程序会在此之前退出。

请注意,我有意2在generatorsfinally块中选择的超时,因此上下文管理器finally有机会在之前运行。如果我1为两个超时都选择了,则将同时打印两条消息。

这是比赛条件吗?我希望所有程序finally块都能在程序完成之前完成。

如何防止上下文finally生成器finally在generators块完成之前运行

对于上下文:

我使用编剧来控制Chrome浏览器。外部上下文管理器提供了一个页面,该页面将在finally块中关闭

我正在使用python 3.9.0

请尝试以下示例:https : //repl.it/@trixn86/AsyncGeneratorRaceCondition

user2357112支持Monica

异步上下文管理器对异步生成器一无所知。实际上main,您对异步生成器一无所知break您没有办法等待生成器的完成。

如果要等待生成器关闭,则需要显式处理关闭操作:

async def main():
    async with async_context():
        gen = async_gen()
        try:
            async for _ in gen:
                break
        finally:
            await gen.aclose()

在Python 3.10中,您可以使用contextlib.aclosing而不是try / finally:

async def main():
    async with async_context():
        gen = async_gen()
        async with contextlib.aclosing(gen):
            async for _ in gen:
                break

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章