【问题标题】:Catch errors in asyncio.ensure_future在 asyncio.ensure_future 中捕获错误
【发布时间】:2016-08-28 08:34:06
【问题描述】:

我有这个代码:

try:
    asyncio.ensure_future(data_streamer.sendByLatest())
except ValueError as e:
    logging.debug(repr(e))

data_streamer.sendByLatest() 可以引发ValueError,但不会被捕获。

【问题讨论】:

    标签: python python-3.x exception python-asyncio


    【解决方案1】:

    ensure_future - 只创建Task 并立即返回。您应该等待创建的任务以获取它的结果(包括引发异常的情况):

    import asyncio
    
    
    async def test():
        await asyncio.sleep(0)
        raise ValueError('123')
    
    
    async def main():    
        try:
            task = asyncio.ensure_future(test())  # Task aren't finished here yet 
            await task  # Here we await for task finished and here exception would be raised 
        except ValueError as e:
            print(repr(e))
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
    

    输出:

    ValueError('123',)
    

    如果您不打算在创建任务后立即等待它,您可以稍后等待它(以了解它是如何完成的):

    async def main():    
        task = asyncio.ensure_future(test())
        await asyncio.sleep(1)
        # At this moment task finished with exception,
        # but we didn't retrieved it's exception.
        # We can do it just awaiting task:
        try:
            await task  
        except ValueError as e:
            print(repr(e)) 
    

    输出相同:

    ValueError('123',)
    

    【讨论】:

    • 谢谢。你还知道如何使用call_soon_threadsafe() 捕获异常吗?
    • @MarcoSulla 抱歉,我不知道。我看到的一种方法是使用包装器来处理回调中的异常:pastebin.com/rNyTWMBk 但我不知道这是否是常见的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    相关资源
    最近更新 更多