【问题标题】: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)
    

    【讨论】:

    • 感谢您的回答。您让我放心使用回调。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多