Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有异步IO队列的Python CanceledError_Python_Queue_Python Asyncio_Producer Consumer - Fatal编程技术网

带有异步IO队列的Python CanceledError

带有异步IO队列的Python CanceledError,python,queue,python-asyncio,producer-consumer,Python,Queue,Python Asyncio,Producer Consumer,我使用应答中的代码,但在队列为空时获取asyncio.exceptions.CancelleError。在RealProject中,我将任务添加到来自使用者的队列中,这就是为什么我使用而True语句的原因 我压缩该代码以使调试更容易: import asyncio import traceback async def consumer(queue: asyncio.Queue): try: while True: number = await

我使用应答中的代码,但在队列为空时获取
asyncio.exceptions.CancelleError
。在RealProject中,我将任务添加到来自使用者的队列中,这就是为什么我使用
而True
语句的原因

我压缩该代码以使调试更容易:

import asyncio
import traceback


async def consumer(queue: asyncio.Queue):
    try:
        while True:
            number = await queue.get()  # here is exception
            queue.task_done()
            print(f'consumed {number}')
    except BaseException:
        traceback.print_exc()


async def main():
    queue = asyncio.Queue()
    for i in range(3):
        await queue.put(i)
    consumers = [asyncio.create_task(consumer(queue)) for _ in range(1)]
    await queue.join()
    for c in consumers:
        c.cancel()


asyncio.run(main())
和错误:

consumed 0
consumed 1
consumed 2
Traceback (most recent call last):
  File "/Users/abionics/Downloads/BaseAsyncScraper/ttt.py", line 8, in consumer
    number = await queue.get()
  File "/usr/local/Cellar/python@3.9/3.9.4/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/queues.py", line 166, in get
    await getter
asyncio.exceptions.CancelledError

顺便说一下,
queue.get()
的文档中说,
如果队列为空,请等待项目可用
。这一错误的真正原因是什么?也许有更好的解决方案?

原因是您取消了任务:

:

请求取消任务

这将安排将CanceledError异常抛出到 在事件循环的下一个周期上包装协同路由

您有几个选项可以处理此问题:

1。使用

如果return_exceptions为True,则将异常视为 成功的结果,并在结果列表中聚合

2。捕获消费者中的异常

async def consumer(q):
    while True:
        try:
            num = await q.get()
            print(f"Working on: {num}")
        except asyncio.CancelledError:
            print(f"Exiting...")
            break
        else:
            q.task_done()
3。抑制异常

form contextlib import suppress

async def consumer(q):
    with suppress(asyncio.CancelledError):
        while True:
            num = await q.get()
            print(f"Working on: {num}")
            q.task_done()
form contextlib import suppress

async def consumer(q):
    with suppress(asyncio.CancelledError):
        while True:
            num = await q.get()
            print(f"Working on: {num}")
            q.task_done()