如何让time.sleep仅作用于部分代码?实现多通道消息定时间隔发送
分时段间隔发送消息的解决方案
问题原因
- 使用
time.sleep():这是同步阻塞函数,会冻结整个异步事件循环,导致所有其他协程(包括其他通道的消息处理)暂停,完全不符合异步场景需求。 - 直接在
myfunc中用asyncio.sleep():每个新消息触发的协程会独立执行,多个协程会同时进入睡眠,到期后同时发送消息,无法实现同通道消息依次间隔发送的效果。
解决方案:异步队列实现顺序发送
通过为每个输出通道创建独立的异步队列,将消息发送任务解耦:事件处理器只负责把消息放入对应队列,由专门的消费协程按顺序取出消息,发送后等待指定间隔,确保同通道消息按要求间隔发送,且不影响其他协程运行。
修改后的代码示例
import asyncio from telethon import TelegramClient, events # 假设已完成client的初始化配置(api_id, api_hash等) client = TelegramClient(...) # 为每个输出通道创建异步队列 output_queue1 = asyncio.Queue() output_queue2 = asyncio.Queue() output_queue3 = asyncio.Queue() # 队列消费协程:负责按间隔发送对应队列的消息 async def send_from_queue(queue, output_channel, delay_seconds): while True: # 等待队列中有消息 message = await queue.get() # 发送消息 await client.send_message(output_channel, message) # 发送后等待指定间隔(30分钟=1800秒) await asyncio.sleep(delay_seconds) # 标记任务完成(可选,用于队列的join操作) queue.task_done() # 输入通道1的事件处理器:将消息放入对应队列 @client.on(events.NewMessage(chats=input_channel1)) async def event_handler1(event): await output_queue1.put(event.message) # 输入通道2的事件处理器 @client.on(events.NewMessage(chats=input_channel2)) async def event_handler2(event): await output_queue2.put(event.message) # 输入通道3的事件处理器 @client.on(events.NewMessage(chats=input_channel3)) async def event_handler3(event): await output_queue3.put(event.message) async def main(): # 启动三个队列的消费任务(后台运行) asyncio.create_task(send_from_queue(output_queue1, output_channel1, 1800)) asyncio.create_task(send_from_queue(output_queue2, output_channel2, 1800)) asyncio.create_task(send_from_queue(output_queue3, output_channel3, 1800)) # 启动客户端并保持运行 await client.start() await client.run_until_disconnected() if __name__ == "__main__": asyncio.run(main())
关键说明
- 每个输出通道对应一个队列和消费协程,不同通道的发送任务完全独立,互不干扰。
- 消费协程采用无限循环,持续监听队列,确保有消息就按顺序处理。
asyncio.sleep()仅在消费协程中使用,且是在发送完一条消息后才进入睡眠,保证了同通道消息的间隔效果。- 事件处理器仅执行入队操作,耗时极短,不会阻塞事件循环。
内容的提问来源于stack exchange,提问作者amir
相关产品推荐
相关产品推荐

