等待异步.Future引发concurrent.foression._base.CancelledError,而不是等待设置值/异常

本教程将介绍等待异步.Future引发concurrent.foression._base.CancelledError,而不是等待设置值/异常的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

等待异步.Future引发concurrent.foression._base.CancelledError,而不是等待设置值/异常 教程 第1张

问题描述

当我运行以下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>

我在此代码中做错了什么?我希望能够等待"将来"fut,并在"将来"设置了值/例外后继续。

推荐答案

您的问题是asyncio.gather is itself async(返回一个可等待的);通过不执行await,您从未将控制权交还给事件循环,也没有存储可等待的对象,因此它立即被清除,隐式取消它,进而取消它控制的所有等待项。

要修复,只需确保awaitgather的结果:

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

Try it online!

好了关于等待异步.Future引发concurrent.foression._base.CancelledError,而不是等待设置值/异常的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。