Await Future from Executor: Future can't be used in 'await' expression

匿名 (未验证) 提交于 2019-12-03 03:06:01

问题:

I wanted to use a ThreadPoolExecutor from a python coroutine, to delegate some blocking network calls to a separate thread. However, running the following code:

from concurrent.futures import ThreadPoolExecutor import asyncio  def work():   # do some blocking io   pass  async def main():   executor = ThreadPoolExecutor()   await executor.submit(work)  loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close() 

causes error:

TypeError: object Future can't be used in 'await' expression 

Aren't Future objects awaitable? Why does it say they aren't?

How can I await a Future object returned by executor.submit?

Python 3.5.0

EDIT

Using executor.submit is not my decision. This is used internally by several libraries, like requests-futures. I am searching for a way to interop with those modules from coroutines.

回答1:

You should use loop.run_in_executor:

from concurrent.futures import ThreadPoolExecutor import asyncio  def work():   # do some blocking io   pass  async def main(loop):   executor = ThreadPoolExecutor()   await loop.run_in_executor(executor, work)  loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) loop.close() 

EDIT

concurrent.futures.Future object are different from asyncio.Future. The asyncio.Future is intended to be used with event loops and is awaitable, while the former isn't. loop.run_in_executor provides the necessary interoperability between the two.

EDIT #2

Using executor.submit is not my decision. This is used internally by several libraries, like requests-futures. I am searching for a way to interop with those modules from coroutines.

Although undocumented, you can use asyncio.wrap_future(future, *, loop=None) to convert a concurrent.futures.Future to a asyncio.Future.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!