在python3中清除asyncio队列的正确方法?

时间:2017-09-10 12:09:52

标签: python python-3.x python-asyncio

我的生产者/消费者协程中的错误可能会将项目和未完成的任务留在asyncio队列中。如果遇到错误,我想简单地停止循环,取消挂起的任务并清除队列。虽然我可以完成前两件事,但我找不到一个简单的方法来清除队列。阅读this answer后,我提出了三种方法:

import asyncio

q=asyncio.Queue()
for i in range(5):
    q.put_nowait(i)
q.get_nowait()

loop=asyncio.get_event_loop()

#this will raise an error if q cannot join
loop.run_until_complete(asyncio.wait_for(q.join(),1))

#method 1
q._queue.clear()
q._finished.set()
q._unfinished_tasks = 0

#method 2
for _ in range(q.qsize()):
    q.get_nowait()
for _ in range(q._unfinished_tasks):
    q.task_done()

#method 3
del q
q=asyncio.Queue()

哪一个更好?

2 个答案:

答案 0 :(得分:0)

我在各种DBussy example scripts中做到了这一点:

for task in asyncio.Task.all_tasks(loop) :
    task.cancel()
    try :
        loop.run_until_complete(task)
    except asyncio.CancelledError :
        pass
    #end try
#end for

答案 1 :(得分:0)

避免使用“私有”方法。来自Queue.task_done的文档:

对于用于提取任务的每个get(),随后对task_done()的调用将告诉队列该任务的处理已完成。

  test "lack of internet connection", %{bypass: bypass} do
    Bypass.down(bypass)

    execute_main = fn ->
      ExTldr.main([])
    end

    assert capture_io(execute_main) =~ "There is not internet connection"
  end