Asyncio 等待处理异常有时会失败?
Asyncio wait handling Exception sometimes fails?
我已经设置了一个异步循环来创建有限制的任务列表。
while current_index < len(numbers):
if len(tasks) >= NO_CONCURRENT:
_done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
task: Task = next(iter(_done))
try:
task.result()
except Exception as e:
logging.error(f"Error: occured {e}")
results.append(task.exception())
else:
results.append(task.result())
它有时会成功处理异常(也记录错误)
但有时甚至不处理它只是打印出异常(不记录它)
例子
2021-07-21,03:53:55.082 ERROR {base_events} [default_exception_handler] Task exception was never retrieved
future: <Task finished name='Task-16' coro=<AutoPart.get_all_info() done, defined at /mnt/d/PythonProjects/btyu-part-num-search/copy_main.py:258> exception=PartNumberNotFound('Part number 14111047 is NOT Found.')>
Traceback (most recent call last):
File "/mnt/d/PythonProjects/btyu-part-num-search/copy_main.py", line 260, in get_all_info
listing_container_id_num = await self.get_part_number(session)
File "/mnt/d/PythonProjects/btyu-part-num-search/copy_main.py", line 141, in get_part_number
raise PartNumberNotFound(self.part_number)
copy_main.PartNumberNotFound: Part number 14112106479456 is NOT Found.
您的代码无法处理两个任务恰好在同一事件循环迭代中完成的情况。在这种情况下,asyncio 返回的 done
集将包含多个元素,尽管请求的是“第一个”已完成。在这种情况下,您将只能访问第一个任务的结果,而第二个任务将在没有任何人访问其异常的情况下被销毁,正如警告中正确指出的那样。
你应该用一个循环来处理它:
while current_index < len(numbers):
if len(tasks) >= NO_CONCURRENT:
done, _ = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
for task in done:
try:
task.result()
except Exception as e:
logging.error(f"Error: occured {e}")
results.append(task.exception())
else:
results.append(task.result())
另外,请注意,变量名前面的首字母 _
是您 不 使用的值的约定,而不是您使用的值使用.
我已经设置了一个异步循环来创建有限制的任务列表。
while current_index < len(numbers):
if len(tasks) >= NO_CONCURRENT:
_done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
task: Task = next(iter(_done))
try:
task.result()
except Exception as e:
logging.error(f"Error: occured {e}")
results.append(task.exception())
else:
results.append(task.result())
它有时会成功处理异常(也记录错误) 但有时甚至不处理它只是打印出异常(不记录它)
例子
2021-07-21,03:53:55.082 ERROR {base_events} [default_exception_handler] Task exception was never retrieved
future: <Task finished name='Task-16' coro=<AutoPart.get_all_info() done, defined at /mnt/d/PythonProjects/btyu-part-num-search/copy_main.py:258> exception=PartNumberNotFound('Part number 14111047 is NOT Found.')>
Traceback (most recent call last):
File "/mnt/d/PythonProjects/btyu-part-num-search/copy_main.py", line 260, in get_all_info
listing_container_id_num = await self.get_part_number(session)
File "/mnt/d/PythonProjects/btyu-part-num-search/copy_main.py", line 141, in get_part_number
raise PartNumberNotFound(self.part_number)
copy_main.PartNumberNotFound: Part number 14112106479456 is NOT Found.
您的代码无法处理两个任务恰好在同一事件循环迭代中完成的情况。在这种情况下,asyncio 返回的 done
集将包含多个元素,尽管请求的是“第一个”已完成。在这种情况下,您将只能访问第一个任务的结果,而第二个任务将在没有任何人访问其异常的情况下被销毁,正如警告中正确指出的那样。
你应该用一个循环来处理它:
while current_index < len(numbers):
if len(tasks) >= NO_CONCURRENT:
done, _ = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
for task in done:
try:
task.result()
except Exception as e:
logging.error(f"Error: occured {e}")
results.append(task.exception())
else:
results.append(task.result())
另外,请注意,变量名前面的首字母 _
是您 不 使用的值的约定,而不是您使用的值使用.