【问题标题】:Python asyncio: exit program immediately if a task throws exceptionPython asyncio:如果任务抛出异常,则立即退出程序
【发布时间】:2020-06-26 15:19:08
【问题描述】:
我使用 asyncio.create_task() 创建了数量不定的长时间运行的任务。如果这些任务中的任何一个引发异常,我想立即优雅地退出我的程序。我不能 asyncio.wait() 任务,因为并非所有任务都是同时创建的(一些正在运行的任务根据需要在不同的时间创建新任务)。
我的想法是在任务完成时使用 Task.add_done_callback() 得到通知,但是 Python 文档建议这应该仅用于低级回调代码,是否有替代方案?
【问题讨论】:
标签:
python-3.x
python-asyncio
【解决方案1】:
如果您控制创建任务的代码,您可以包装任务协程以捕获异常并根据需要处理失败。例如,如果任务是这样创建的:
# let some_coro() run unattended
asyncio.create_task(some_coro())
你可以修改如下:
async def run_guarded(aw):
try:
await aw
except:
import traceback, sys
traceback.print_exc()
sys.exit(1)
asyncio.create_task(run_guarded(some_coro()))
如果您无法修改生成任务的位置,则需要使用add_done_callback。不要担心它是“低级”的,该警告只是为了防止过度使用回调,并在可能的情况下将用户推向awaiting。这种用例正是add_done_callback 所擅长的。
def check_error(t):
if not t.cancelled() and t.exception() is not None:
import traceback, sys
e = t.exception()
traceback.print_exception(None, e, e.__traceback__)
sys.exit(1)
# task previously created with create_task()
task.add_done_callback(check_error)