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)