首页 文章

python3 asyncio等待回调

提问于
浏览
1

我现在成功了 . 我的想法是为行动的 done_callback 添加一个asyncio未来,但未来似乎永远不会完成 .

代码在这里:

def _generate_action_executor(self, action):

    async def run_action(goal):
        action_done = asyncio.Future()

        def done_callback(goal_status, result, future):
            status = ActionLibGoalStatus(goal_status)
            print('Action Done: {}'.format(status))
            future.set_result(result)

        action.send_goal(goal,
                         lambda x, y: done_callback(x,
                                                    y,
                                                    action_done))
        try:
            result = await action_done
            #problem future never done
        except asyncio.CancelledError as exc:
            action.cancel()
            raise exc

        return result

    return run_action

async def do_some_other_stuff(action):
    //do stuff
    my_goal = MyActionRequest('just do it')

    run_action = self._generate_action_executor(action)

    response = await run_action(my_goal)

    return response


if __name__ == "__main__":
    action = actionlib.SimpleActionClient('my_action',
                                           MyAction)

    try:
        loop = asyncio.get_event_loop()

        loop.run_until_complete(do_some_other_stuff(action))
    finally:
        loop.close()

2 回答

  • 0

    请记住,asyncio意味着在单个线程中运行 .

    如果程序需要与其他线程交互,则必须使用其中一个专用函数:

    这是一个简化的例子:

    async def run_with_non_asyncio_lib(action, arg):
        future = asyncio.Future()
        loop = asyncio.get_event_loop()
    
        def callback(*args):
            loop.call_soon_threasafe(future.set_result, args)
    
        non_asyncio_lib.register_callback(action, arg, callback)
        callback_args = await future
        return process(*callback_args)
    

    或者,loop.run_in_executor提供了一种通过在自己的线程中运行给定函数来与非asyncio库交互的方法:

    async def run_with_non_asyncio_lib(action, arg):
        loop = asyncio.get_event_loop()
        future = loop.run_in_executor(None, non_asyncio_lib.run, action, arg)
        result = await future
        return result
    
  • 0

    随着文森特的想法,

    我实际上找到了解决问题的方法:

    def _generate_action_executor(action):
        async def run_action(goal):
            loop = asyncio.get_event_loop()
            action_done = loop.create_future()
    
            def done_callback(goal_status, result, future, loop):
                status = ActionLibGoalStatus(goal_status)
                print('Action Done: {}'.format(status))
                loop.call_soon_threadsafe(future.set_result(result))
    
            action.send_goal(goal,partial(done_callback, future=action_done, loop=loop))
            try:
                await action_done
            except asyncio.CancelledError as exc:
                action.cancel()
                raise exc
    
            return action_done.result()
    
        return run_action
    

    如果有人知道如何以更智能的方式实现它,请与使用者分享这些知识 .

    最好的曼努埃尔

相关问题