解决python-telegram-bot重复发消息时Event loop is closed错误
问题
使用python-telegram-bot v21.0.1和Python 3.10版本,尝试间隔几秒发送两条消息,第一条消息发送成功,但第二次发送时出现RuntimeError: Event loop is closed错误。
出错代码
asyncio.run(bot.send_message('-0000', text=alert)) sleep(5) asyncio.run(bot.send_message('-0000', text=alert))
回溯信息
Traceback (most recent call last): File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\telegram\request\_baserequest.py", line 330, in _request_wrapper code, payload = await self.do_request( File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\telegram\request\_httpxrequest.py", line 276, in do_request res = await self._client.request( File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_client.py", line 1574, in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_client.py", line 1661, in send response = await self._send_handling_auth( File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_client.py", line 1689, in _send_handling_auth response = await self._send_handling_redirects( File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_client.py", line 1726, in _send_handling_redirects response = await self._send_single_request(request) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_client.py", line 1763, in _send_single_request response = await transport.handle_async_request(request) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpx\_transports\default.py", line 373, in handle_async_request resp = await self._pool.handle_async_request(req) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\connection_pool.py", line 216, in handle_async_request raise exc from None File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\connection_pool.py", line 196, in handle_async_request response = await connection.handle_async_request( File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\connection.py", line 101, in handle_async_request return await self._connection.handle_async_request(request) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\http11.py", line 142, in handle_async_request await self._response_closed() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\http11.py", line 257, in _response_closed await self.aclose() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_async\http11.py", line 265, in aclose await self._network_stream.aclose() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\httpcore\_backends\anyio.py", line 54, in aclose await self._stream.aclose() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio\streams\tls.py", line 202, in aclose await self.transport_stream.aclose() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\site-packages\anyio\_backends\_asyncio.py", line 1191, in aclose self._transport.close() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\asyncio\proactor_events.py", line 109, in close self._loop.call_soon(self._call_connection_lost, None) File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 753, in call_soon self._check_closed() File "C:\Users\A\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 515, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed
解决方案
错误原因
asyncio.run()每次调用会创建新的事件循环,执行完协程后自动关闭循环。第二次调用时,底层HTTP连接仍试图使用已关闭的旧循环,触发报错。- 同步的
sleep(5)会阻塞线程,破坏异步代码的执行逻辑,加重循环相关问题。
修复代码
将两次消息发送逻辑整合到同一个异步函数中,用异步的asyncio.sleep()实现间隔,仅通过一次asyncio.run()执行整个流程:
import asyncio from telegram import Bot async def send_messages(): bot = Bot(token='你的BotToken') # 确保在此处正确初始化Bot实例 await bot.send_message('-0000', text=alert) await asyncio.sleep(5) # 异步等待5秒,不阻塞事件循环 await bot.send_message('-0000', text=alert) asyncio.run(send_messages())
额外注意事项
- Bot实例需在同一个事件循环生命周期内复用,避免跨循环使用实例。
- 异步代码中禁止混用同步阻塞函数(如
time.sleep()),全部改用异步等待方法。
内容的提问来源于stack exchange,提问作者Robsmith
相关产品推荐
相关产品推荐

