如何在 python 中结合同步对象迭代和异步代码?
How to combine sync object iteration and async code in python?
我有一个对象列表,对于每个对象,我都需要对其进行一些异步处理。我不确定我是否构造正确:
def run(tasks):
async def async_wrapper():
async def update_task():
updated_task = await task_manager.async_get_task_status(session, task)
# do some works with updated_task
workers = []
resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
for local_task in tasks: # tasks is a list of object
await update_ocr_task()
loop = asyncio.get_event_loop()
loop.run_until_complete(aysnc_wrapper())
我认为 for 循环是同步的,会完全阻止进度,对吗?如果我是,如何构建?
def run(tasks):
# ...
loop = asyncio.get_event_loop()
loop.run_until_complete(aysnc_wrapper())
通常这不是人们编写异步程序的方式:事件循环应该是全局的并且作为整个脚本的主要入口点启动。像你一样做(运行单个函数内的事件循环 run
)使得上层代码无法 运行 同一事件循环中的其他协程。
如果您了解这一点,并且您想要的只是阻止无法与其他异步内容一起使用的 run
函数,请进一步阅读。
您的 async_wrapper
的问题在于它仅在前一个协程完成后才等待下一个 update_ocr_task()
协程。 For 循环不是我们所说的 "blocking",但它不是并发的 - 它不使用异步范例提供的好处。
要获得使用 asyncio 的好处,您应该 运行 同时使用多个协程。常用的方法是使用 asyncio.gather():
async def async_wrapper():
async def process_single_task(task):
resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
await session.get(...) # do all job for *single* local task here.
# Run multiple task processing coroutines concurrently:
await asyncio.gather(
*[process_single_task(t) for t in tasks]
)
如果需要,您还可以阅读 关于 asyncio 的一般性回答。
我有一个对象列表,对于每个对象,我都需要对其进行一些异步处理。我不确定我是否构造正确:
def run(tasks):
async def async_wrapper():
async def update_task():
updated_task = await task_manager.async_get_task_status(session, task)
# do some works with updated_task
workers = []
resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
for local_task in tasks: # tasks is a list of object
await update_ocr_task()
loop = asyncio.get_event_loop()
loop.run_until_complete(aysnc_wrapper())
我认为 for 循环是同步的,会完全阻止进度,对吗?如果我是,如何构建?
def run(tasks):
# ...
loop = asyncio.get_event_loop()
loop.run_until_complete(aysnc_wrapper())
通常这不是人们编写异步程序的方式:事件循环应该是全局的并且作为整个脚本的主要入口点启动。像你一样做(运行单个函数内的事件循环 run
)使得上层代码无法 运行 同一事件循环中的其他协程。
如果您了解这一点,并且您想要的只是阻止无法与其他异步内容一起使用的 run
函数,请进一步阅读。
您的 async_wrapper
的问题在于它仅在前一个协程完成后才等待下一个 update_ocr_task()
协程。 For 循环不是我们所说的 "blocking",但它不是并发的 - 它不使用异步范例提供的好处。
要获得使用 asyncio 的好处,您应该 运行 同时使用多个协程。常用的方法是使用 asyncio.gather():
async def async_wrapper():
async def process_single_task(task):
resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
await session.get(...) # do all job for *single* local task here.
# Run multiple task processing coroutines concurrently:
await asyncio.gather(
*[process_single_task(t) for t in tasks]
)
如果需要,您还可以阅读