web-dev-qa-db-ja.com

エグゼキュータからのAwaitFuture:「await」式でFutureを使用することはできません

python coroutine から ThreadPoolExecutor を使用して、ブロッキングネットワーク呼び出しを別のスレッドに委任したいと思いました。ただし、次のコードを実行します。

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()

エラーの原因:

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

Futureオブジェクト待機可能ではありませんか?なぜそうではないと言うのですか?

executor.submitから返されたawaitオブジェクトをFutureするにはどうすればよいですか?

Python 3.5.0

[〜#〜]編集[〜#〜]

executor.submitを使用することは私の決定ではありません。これは、 requests-futures などのいくつかのライブラリによって内部的に使用されます。コルーチンからこれらのモジュールと相互運用する方法を探しています。

13
Tamas Hegedus

_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()
_

[〜#〜]編集[〜#〜]

_concurrent.futures.Future_ オブジェクトは _asyncio.Future_ とは異なります。 _asyncio.Future_は、イベントループで使用することを目的としており、待機可能ですが、前者はそうではありません。 _loop.run_in_executor_は、2つの間に必要な相互運用性を提供します。

編集#2

Executor.submitを使用することは私の決定ではありません。これは、requests-futuresのように、いくつかのライブラリによって内部的に使用されます。コルーチンからこれらのモジュールと相互運用する方法を探しています。

編集#3

python 3.5( docs )なので、asyncio.wrap_future(future, *, loop=None)を使用して_concurrent.futures.Future_を_asyncio.Future_に変換できます。

22
Jashandeep Sohi