【问题标题】:as_completed identifying coroutie objectsas_completed 识别 cooutie 对象
【发布时间】:2021-01-12 19:32:55
【问题描述】:

我正在使用 asyncio 通过以下方式等待一组协程:

# let's assume we have fn defined and that it can throw an exception

coros_objects = []
for x in range(10):
    coros_objects.append(fn(x))


for c in asyncio.as_completed(coros_objects):
    try:
       y = await c
    exception:
       # something
       # if possible print(x)

问题是我如何知道哪个协程失败了,以及哪个参数失败了? 我可以将"x" 附加到输出中,但这只会为我提供有关成功执行的信息。

我可以知道表单顺序,因为它与coros_objects 的顺序不同

我能否以某种方式确定 coro 刚刚产生了什么结果?

【问题讨论】:

    标签: python-asyncio coroutine


    【解决方案1】:

    问题是我如何知道哪个协程失败了以及针对哪个参数?

    您不能使用当前的as_completed。一旦this PR 被合并,就可以通过将信息附加到未来(因为as_completed 将产生原始期货)。目前有两种解决方法:

    • 将协程执行包装在一个包装器中,该包装器捕获异常并存储它们,还存储您需要的原始参数,或者
    • 根本不使用as_completed,而是使用asyncio.wait 等工具编写自己的循环。

    第二个选项比大多数人预期的要容易,所以这里是(未经测试):

    # create a list of tasks and attach the needed information to each
    tasks = []
    for x in range(10):
        t = asyncio.create_task(fn(x))
        t.my_task_arg = x
        tasks.append(t)
    
    # emulate as_completed with asyncio.wait()
    while tasks:
        done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        for t in done:
            try:
                y = await t
            except Exception as e:
                print(f'{e} happened while processing {t.my_task_arg}')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-13
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2021-02-07
      相关资源
      最近更新 更多