При использовании asyncio.Queue () как отменить получение? - PullRequest
1 голос
/ 12 июля 2020

Я пишу клиента в asyncio и использую q.get () для ожидания ответов от сервера. Когда я получаю ответ от сервера, я помещаю его в очередь. Если соединение с сервером потеряно, я больше не буду выполнять эти операции, и у меня может быть любое количество await q.get ().

Как мне отменить их? Я заметил, что когда я удаляю очередь, await все еще ждет.

1 Ответ

1 голос
/ 12 июля 2020

Похоже ли это на то, что вы пытаетесь сделать? Я думаю, у вас есть два варианта:

Если вы ведете подсчет невыполненных получений, то, когда вы закончите с очередью, вы можете просто поставить (Нет) столько раз?

Или, если Нет действительный ответ, затем сохраните список невыполненных фьючерсов и вызовите отмену для них самостоятельно.

import asyncio

async def qget(q):
  try:
    x = await q.get()
    q.task_done()
    print("qget done ",x)
  except asyncio.CancelledError as e:
    print("qget cancel exception ",e)
  except Exception as e:
    print("qget exception ",e)

async def run():

  q = asyncio.Queue()
  futs = []
  futs.append( asyncio.ensure_future( qget(q) ) )
  futs.append( asyncio.ensure_future( qget(q) ) )
  num = 2

  await asyncio.sleep(0.1)

  # Keep the number of outstanding gets and put None for each one
  if 1:
    for x in range(num):
      q.put_nowait(None)

  # Or keep the futures in a list and cancel them
  if 0:
    for f in futs:
      f.cancel()

  await asyncio.sleep(1)
  print("run loop done")


asyncio.run(run())

Если вы посмотрите на код python для очереди , список называется _getters, но отсутствует publi c api для доступа к нему.

...