Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Python-在异步IO中取消任务?_Python_Asynchronous_Async Await_Python Asyncio - Fatal编程技术网

Python-在异步IO中取消任务?

Python-在异步IO中取消任务?,python,asynchronous,async-await,python-asyncio,Python,Asynchronous,Async Await,Python Asyncio,我已经在下面为异步池编写了代码。在\uuuu aexit\uuuu中,我将在任务完成后取消工作任务。但是当我运行代码时,辅助任务不会被取消,代码将永远运行。这就是任务的外观:当您创建了一个asyncio任务并将其取消时,您仍然有需要“回收”的活动任务。所以你要等待工人来处理它。但是,一旦等待这样一个已取消的任务,因为它永远不会返回预期的返回值,就会引发asyncio.cancelerederError,您需要在某个地方捕获它 由于这种行为,我认为您不应该收集他们,而应该等待每个被取消的任务,因为

我已经在下面为异步池编写了代码。在
\uuuu aexit\uuuu
中,我将在任务完成后取消工作任务。但是当我运行代码时,辅助任务不会被取消,代码将永远运行。这就是任务的外观:
当您创建了一个
asyncio
任务并将其取消时,您仍然有需要“回收”的活动任务。所以你要等待工人来处理它。但是,一旦
等待
这样一个已取消的任务,因为它永远不会返回预期的返回值,就会引发
asyncio.cancelerederError
,您需要在某个地方捕获它

由于这种行为,我认为您不应该
收集他们,而应该
等待每个被取消的任务,因为他们应该马上返回:

async def __aexit__(self,type,value,traceback):
    await self._queue.join()

    for worker in self._workers:
        worker.cancel()
    for worker in self._workers:
        try:
           await worker
        except asyncio.CancelledError:
           print("worker cancelled:", worker)

问题是您的
Exception
Exception子句也捕获取消,并忽略它。为了增加混淆,
print(e)
在出现
cancelederror
时只打印一个空行,这就是输出中空行的来源。(将其更改为
print(type(e))
显示发生了什么。)


要更正此问题,请将
异常除外
更改为更具体的内容,如
异步IO.TimeoutError除外
。在Python 3.8中不需要进行此更改,
asyncio.cancelederror
不再源于
Exception
,而是源于
BaseException
,因此除了Exception
之外的
不会捕捉到它。

请编辑问题,以包含再现该问题的测试代码。当我试图通过添加一个小的
main()
来复制它时,我得到了一个
cancelederror
。这是因为
gather()
等待已取消的任务。将
return\u exceptions=True
添加到
gather
调用修复了此错误,并且未打印任何警告。@user4815162342对此表示抱歉,我用您的示例编辑了问题。您是否尝试添加
return\u exceptions=True
,如我在评论的最后一句中所述?@user4815162342是,它不会返回任何异常。等待集合仍在执行解决您的问题的方法?是否打印了警告?Wait worker也不工作,如果在Wait上方打印,我会得到相同的结果,即
,代码仍在运行,正在等待worker。我正在使用此异步池从tmdb中提取数据。我正面临一个问题,如果可能的话,你能看看这个吗?thanks@Madvillainy我看到了那个问题,但我不知道是怎么回事。在你的位置上,我会尽可能多地放置指纹,看看它卡在哪里。一旦你明白了它在哪里被卡住了,你就会明白为什么会发生以及如何解决它。我会尝试一下。非常感谢。
async def something(item):
    print("got", item)
    await asyncio.sleep(item)
 
async def main():
    async with AsyncPool(something, 5, 2) as pool:
        for i in range(10):
            await pool.push_to_queue(i)
 
asyncio.run(main())
async def __aexit__(self,type,value,traceback):
    await self._queue.join()

    for worker in self._workers:
        worker.cancel()
    for worker in self._workers:
        try:
           await worker
        except asyncio.CancelledError:
           print("worker cancelled:", worker)