代码之家  ›  专栏  ›  技术社区  ›  LtMerlin

如何在python run\u in\u executor方法调用中捕获异常

  •  9
  • LtMerlin  · 技术社区  · 8 年前

    如何在使用run\u in\u执行器调用的run\u long\u thing()函数中引发异常? 它看起来像是被吞下了。我不需要阻塞代码中函数的结果。它基本上是一个fire-and-forget函数,但如果有任何异常,我仍然需要捕捉异常。。。

    import asyncio
    import time
    
    
    def fire_and_forget(task, *args, **kwargs):
        loop = asyncio.get_event_loop()
        if callable(task):
            #if threadpoolworker is set to None,
            #the max_workers will default to the number of processors on the machine, multiplied by 5
            return loop.run_in_executor(None, task, *args, **kwargs)
        else:    
            raise TypeError('Task must be a callable.')
    
    
    async def run_long_thing(sleep):
        print("Doing long thing... {:}".format(sleep))
        time.sleep(sleep)
        print("Done doing long thing. {:}".format(sleep))
        raise Exception("sh*t happens")
    
    
    def do_it():
        print("Starting my main thing...")
        print("Calling my long thing...")
        for i in range(0,10,1):
            try:
                fire_and_forget(run_long_thing, i)
                print(i)
                print("Pom pi dom...")
                time.sleep(0.1)
                print("POOOOM Pom pi dom...")
            except:
                print("can i see the sh*t?")
    
    do_it()
    
    1 回复  |  直到 8 年前
        1
  •  8
  •   Sam Hartman    8 年前

    首先,如果你打电话 time.sleep 你永远都不会跑完 asyncio 时间睡觉 在里面 do_it

    asyncio.get_event_loop().run_until_complete(asyncio.sleep(0.1))
    

    现在,run_in_executor的回报是未来。如果您不介意编写一个异步定义并使用 create_task 在您的 异步 你可以这样做

    async def run_long_thing(thing, *args):
        try: await asyncio.get_event_loop().run_in_executor(None, thing, *args)
        except:
            #do stuff
    

    但更符合您当前的代码,您可以附加一个异常回调

    def callback(future):
    if future.exception(): #your long thing had an exception
            # do something with future.exception()
    

    然后,当您调用run\u in\u executor时:

    future = asyncio.get_event_loop().run_in_executor(None, fun, *args)
    future.add_done_callback(callback)
    

    然后 callback 将在执行器任务完成时调用。 future.result() 如果不例外,则将包含结果,并且 future.exception() 将返回任何引发的异常