在取消未来之前正确关闭 asyncio.ClientSession

Properly closing asyncio.ClientSession before cancelling the future

我有一个正在等待的任务列表,最快的响应将被保存,其余的将被取消

done, pending = await asyncio.wait(
    futures, return_when=FIRST_COMPLETED)

print(done.pop().result())

for future in pending:
    future.cancel()

这些期货中的每一个都有这个

session = asyncio.CreateSession()
# some code to request
# some code to process response
await session.close()

当我取消其他期货时,我收到警告

Unclosed client session client_session: <aiohttp.client.ClientSession object at 0x10f95c6d8>

在取消任务之前关闭此打开的会话的最佳方法是什么?

1)

for future in pending:
    future.cancel()

如果你想取消某些东西,你不仅应该调用 cancel() 方法,还应该等待实际取消的任务:

from contextlib import suppress

for task in pending:
    task.cancel()
    with suppress(asyncio.CancelledError):
        await task

了解取消的工作原理。

2)

session = asyncio.CreateSession()
# some code to request
# some code to process response
await session.close()

并且可以在这行之间的某处引发 CancelledError(或其他异常)。如果发生这种情况,将永远无法到达第 await session.close() 行。

在 Python 中的任何地方,如果您占用了一些资源并且稍后需要释放它,您应该始终将所有代码包装在 taking/freeing 到 try/finally 块之间:

session = asyncio.CreateSession()
try:
    # some code to request
    # some code to process response
finally:
    await session.close()

同样,它是 not only 与 asyncio 相关的常见模式。