如何在aiogram异步代码中等待线程完成?
解决aiogram中callback处理线程同步问题
方案一:直接移除线程(最优,适配当前场景)
你的create_message只是简单的字符串拼接操作,耗时极短,完全不需要额外开线程。直接在异步回调函数中同步调用这个函数即可,不会阻塞asyncio事件循环:
def create_message(response): message = '' for i in response: message += f'• <a href="{i.get("link")}">{i.get("article")}</a>\n\n' return message @dp.callback_query_handler() async def callback_query_keyboard(callback_query: types.CallbackQuery): connection = db.DbConnection() await connection.create_pool() response = await connection.get_data(callback_query.data) # 直接调用同步函数生成消息 message = create_message(response) await bot.send_message( callback_query.from_user.id, text=message, parse_mode='HTML', disable_web_page_preview=True )
方案二:用asyncio.run_in_executor处理耗时同步函数
如果create_message实际包含耗时的CPU绑定操作(比如复杂计算、大量数据处理),可以用asyncio.run_in_executor把同步函数放到线程池执行,既不阻塞事件循环,又能等待函数执行完成获取结果:
def create_message(response): message = '' # 示例:模拟耗时处理逻辑 for i in response: import time time.sleep(0.1) message += f'• <a href="{i.get("link")}">{i.get("article")}</a>\n\n' return message @dp.callback_query_handler() async def callback_query_keyboard(callback_query: types.CallbackQuery): connection = db.DbConnection() await connection.create_pool() response = await connection.get_data(callback_query.data) # 获取当前事件循环,将同步函数提交到线程池执行 loop = asyncio.get_running_loop() message = await loop.run_in_executor(None, create_message, response) await bot.send_message( callback_query.from_user.id, text=message, parse_mode='HTML', disable_web_page_preview=True )
原代码问题分析
- 手动启动线程后,主线程未等待线程完成就调用
out_queue.get(block=False),此时队列大概率为空,会抛出queue.Empty异常导致机器人无响应 await asyncio.sleep(0.2)是不可靠的临时方案:线程执行时间超过0.2秒就会失效,且固定等待会浪费资源
内容的提问来源于stack exchange,提问作者vortexsf24
相关产品推荐
相关产品推荐

