【问题标题】:How to know which coroutines were done with asyncio.wait()如何知道使用 asyncio.wait() 完成了哪些协程
【发布时间】:2015-12-29 10:59:28
【问题描述】:

我有两个StreamReader 对象,想循环读取它们。我像这样使用asyncio.wait

done, pending = await asyncio.wait(
    [reader.read(1000), freader.read(1000)],
    return_when=asyncio.FIRST_COMPLETED)

现在done.pop() 给了我先完成的未来。问题是我不知道如何找到完成了哪个read() 操作。我尝试将[reader.read(1000), freader.read(1000)] 放入tasks 变量中,并将完成的未来与那些进行比较。但这似乎是不正确的,因为完成的未来不等于任何原始任务。那么我应该如何找到哪个协程完成了呢?

【问题讨论】:

  • 您需要从您的呼叫中创建任务并将 那些 传递给wait - 参见例如this example.
  • @jonrsharpe 是的。这样做。谢谢。愿意将其发布为答案吗?
  • 很高兴,会做的。

标签: python python-3.x python-asyncio


【解决方案1】:

您需要为每个.read 调用创建一个单独的任务,并将这些任务传递给.wait。然后,您可以检查 tasks 在结果中的位置。

reader_task = asyncio.ensure_future(reader.read(1000))
...

done, pending = await asyncio.wait(
    [reader_task, ...],
    return_when=asyncio.FIRST_COMPLETED,
)

if reader_task in done:
   ...

...

参见例如this example 来自 websockets 文档。

【讨论】:

  • 另外请注意,一个常见的错误是忽略asyncio.wait 可以被取消(通常在包含协程被取消时)但它创建的任务(或您创建和传递的任务)不是。我通常最终用try/finally 来包装我的asyncio.wait 调用,这会显式取消任务。目前令人讨厌且记录不充分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多