python - 等待 asyncio.Future 引发 concurrent.futures._base.CancelledError 而不是等待设置值/异常

标签 python python-3.x async-await python-asyncio python-3.7

当我运行以下 python 代码时:

import asyncio
import logging
logging.basicConfig(level=logging.DEBUG)

async def read_future(fut):
    print(await fut)

async def write_future(fut):
    fut.set_result('My Value')

async def main():
    loop = asyncio.get_running_loop()
    fut = loop.create_future()
    asyncio.gather(read_future(fut), write_future(fut))

asyncio.run(main(), debug=True)

程序不是 read_future 等待 fut 的结果被设置,而是崩溃并出现以下错误:

DEBUG:asyncio:Using selector: KqueueSelector
ERROR:asyncio:_GatheringFuture exception was never retrieved
future: <_GatheringFuture finished exception=CancelledError() created at /Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/tasks.py:642>
source_traceback: Object created at (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/base_events.py", line 566, in run_until_complete
    self.run_forever()
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/base_events.py", line 534, in run_forever
    self._run_once()
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/base_events.py", line 1763, in _run_once
    handle._run()
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "<stdin>", line 4, in main
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/tasks.py", line 766, in gather
    outer = _GatheringFuture(children, loop=loop)
  File "/Users/<user>/.pyenv/versions/3.7.4/lib/python3.7/asyncio/tasks.py", line 642, in __init__
    super().__init__(loop=loop)
concurrent.futures._base.CancelledError
DEBUG:asyncio:Close <_UnixSelectorEventLoop running=False closed=False debug=True>

我在这段代码中做错了什么?我希望能够等待 Future fut 并在 Future 设置值/异常后继续。

最佳答案

你的问题是asyncio.gather is itself async (返回等待);通过不 await 处理它,您从未将控制权交还给事件循环,也没有存储可等待对象,因此它立即被清理,隐式取消它,并且通过扩展,它的所有可等待对象控制。

要修复,只需确保您await gather 的结果:

await asyncio.gather(read_future(fut), write_future(fut))

Try it online!

关于python - 等待 asyncio.Future 引发 concurrent.futures._base.CancelledError 而不是等待设置值/异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58325846/

相关文章:

c# - 等待和异步用法

javascript - 如何在 forEach 函数上执行异步等待

python - 必须使用 fibo_ 实例作为第一个参数调用未绑定(bind)的方法 f()(改为获取 classobj 实例)

python - asyncio 与同步代码

python - 如何在多行 if 语句中注释每个条件?

python - aiohttp - 如何查看 websocket 消息缓冲区?

javascript - 返回未决的 promise 有实际好处吗?

python - 如何从列表中返回字符串列表?

python - pandas 相当于 Stata 的编码

python - 两个二维数组之间的比较