繁体   English   中英

如何在 Python/Asyncio 中处理未处理的异常?

[英]How to handle unhandled exception in Python/Asyncio?

我有一个任务。

async def task():
    # stuff

我有我的协程

async def coro(tasks):
    tasks = [asyncio.create_task(t) for t in tasks]
    task_iterator = tqdm(asyncio.as_completed(tasks), total=len(tasks))
    result = [await t for t in task_iterator]
    return result

我运行它

try:
    asyncio.run(coro)
except Exception as e:
    # handle error

问题是如果task()失败,我会收到两个错误。 一个错误抱怨unhandled exception in asyncio.run() shutdown task另一个错误抱怨task exception was never retrieved future 两条错误消息都指向task()中发生的事情。

我的问题是

  1. 为什么try...except子句asyncio.run()没有捕捉到这两个问题?

  2. 我能做些什么来抓住他们?

  1. 您不是在主线程中运行coro ,而是在 asyncio 的运行器中运行。 每个任务(带有一些参数的函数调用)都被推到执行队列的后面,一旦没有其他任务执行,它们就会被弹出。 每个任务一旦需要一些 I/O 就会离开执行状态。 在那里,任务将被推送到等待队列,如果 asyncio 的事件循环捕获该任务的相应 I/O 操作,它会将任务移动到执行队列。 总结:当一些任务在等待 I/O 时,其他的可以运行非 I/O 部分。 这就是为什么它被称为 async io

  2. 您可以在coro函数周围使用装饰器并在那里处理异常。 就像是:

def exception_handler(f):
   async def wrapper(*args, **kwargs):
      try:
         return await f(*args, **kwargs)
      except Exception as e:
         print(e)
   return wrapper


@exception_handler
async def coro(tasks):
   ...


asyncio.run(coro, args=([1, 2, 3], ))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM