You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在独立线程运行python-telegram-bot?解决无事件循环报错

独立线程运行Telegram Bot报错解决方案

问题场景

需要在独立线程中运行Telegram Bot以释放主线程,但运行代码时触发RuntimeError: There is no current event loop in thread 'Thread-1'错误。

原测试代码

bot_thread.py

import logging
import asyncio
from telegram import Update
from telegram.ext import Application, ContextTypes, CommandHandler
from threading import Thread
from multiprocessing import Process

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)


class Bot(Thread):
    async def start_msg(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")
    
    def run(self):
        async def hello(update: Update, context: ContextTypes.DEFAULT_TYPE):
            await context.bot.send_message(chat_id=update.effective_chat.id, text="Starting bot")
        
        key = open('../data/keys', 'r').read()
        application = Application.builder().token(key).build()
        
        job_queue = application.job_queue
        job_queue.run_once(hello, 90)
        
        start_handler = CommandHandler('start', self.start_msg)
        application.add_handler(start_handler)
        
        application.run_polling()

bot.py

from bot_thread import Bot

Bot().start()

完整报错信息

> python .\bot_wrapper.py
2024-05-09 15:04:13,916 - apscheduler.scheduler - INFO - Adding job tentatively -- it will be properly scheduled when the scheduler starts
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2032.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 1045, in _bootstrap_inner
    self.run()
  File "bot_thread.py", line 32, in run
    application.run_polling()
  File "AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\telegram\ext\_application.py", line 838, in run_polling
    return self.__run(
           ^^^^^^^^^^^
  File "AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\telegram\ext\_application.py", line 1020, in __run
    loop = asyncio.get_event_loop()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2032.0_x64__qbz5n2kfra8p0\Lib\asyncio\events.py", line 677, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2032.0_x64__qbz5n2kfra8p0\Lib\threading.py:1047: RuntimeWarning: coroutine 'Updater.start_polling' was never awaited
  self._invoke_excepthook(self)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

错误原因

Python的asyncio事件循环默认仅在主线程中自动创建,手动启动的子线程不会生成默认事件循环。而Telegram Bot的run_polling()方法依赖asyncio事件循环,因此在子线程中直接调用会触发找不到事件循环的错误。另外原代码中hello函数的参数不符合job_queue回调要求,会导致额外异常。

修复方案

在子线程的run()方法中手动创建并设置asyncio事件循环,将Bot的异步逻辑封装到单独的协程函数中,再通过事件循环运行。同时修正job_queue回调函数的参数格式。

修复后的bot_thread.py

import logging
import asyncio
from telegram import Update
from telegram.ext import Application, ContextTypes, CommandHandler
from threading import Thread

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)


class Bot(Thread):
    async def start_msg(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
        await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")
    
    async def run_bot(self):
        # 修正job_queue回调参数:仅接收Context参数
        async def hello(context: ContextTypes.DEFAULT_TYPE):
            # 此处需替换为你的测试聊天ID,或调整逻辑获取目标chat_id
            await context.bot.send_message(chat_id="你的测试ChatID", text="Starting bot")
        
        key = open('../data/keys', 'r').read()
        application = Application.builder().token(key).build()
        
        start_handler = CommandHandler('start', self.start_msg)
        application.add_handler(start_handler)
        
        # 启动job_queue并添加任务
        await application.job_queue.start()
        application.job_queue.run_once(hello, 90)
        
        # 运行polling
        await application.run_polling()
    
    def run(self):
        # 子线程手动创建并设置事件循环
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            loop.run_until_complete(self.run_bot())
        finally:
            loop.close()

内容的提问来源于stack exchange,提问作者DevBush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:53:10