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

使用python-telegram-bot与asyncio遇Event Loop Already Running错误求助

解决python-telegram-bot异步运行时的事件循环错误

错误原因

你遇到的RuntimeError: This event loop is already running和Cannot close a running event loop,核心问题是重复调用了事件循环相关的阻塞逻辑:

  • application.run_polling()本身是阻塞式异步函数,内部已包含维持Bot运行、等待停止信号的逻辑
  • 额外添加的await application.idle()会再次尝试占用事件循环,导致冲突

修复方案

方案1:仅使用run_polling()(推荐)

删除多余的await application.idle(),直接用run_polling()维持Bot运行:

import asyncio
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters
from imdb import IMDb

# 确保处理器为异步函数
async def init(update, context):
    await update.message.reply_text("欢迎使用电影推荐Bot!请输入你喜欢的电影类型")

async def genres_selected(update, context):
    # IMDbPY是同步库,用asyncio.to_thread避免阻塞事件循环
    ia = IMDb()
    movies = await asyncio.to_thread(ia.search_movie, update.message.text)
    if movies:
        await update.message.reply_text(f"为你推荐:{movies[0]['title']} ({movies[0].get('year', '')})")
    else:
        await update.message.reply_text("未找到相关电影")

async def main():
    application = ApplicationBuilder().token("YOUR_BOT_TOKEN").build()

    # 添加处理器
    application.add_handler(CommandHandler("start", init))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, genres_selected))

    # run_polling会一直运行直到收到停止信号(比如Ctrl+C)
    await application.run_polling()

if __name__ == '__main__':
    asyncio.run(main())

方案2:使用start_polling() + idle()

若需要更灵活控制Bot启动/停止流程,可启动轮询任务后用idle()等待停止:

import asyncio
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters
from imdb import IMDb

async def init(update, context):
    await update.message.reply_text("欢迎使用电影推荐Bot!请输入你喜欢的电影类型")

async def genres_selected(update, context):
    ia = IMDb()
    movies = await asyncio.to_thread(ia.search_movie, update.message.text)
    if movies:
        await update.message.reply_text(f"为你推荐:{movies[0]['title']} ({movies[0].get('year', '')})")
    else:
        await update.message.reply_text("未找到相关电影")

async def main():
    application = ApplicationBuilder().token("YOUR_BOT_TOKEN").build()

    application.add_handler(CommandHandler("start", init))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, genres_selected))

    # 启动轮询任务(非阻塞)
    await application.start_polling()
    # 等待Bot停止信号
    await application.idle()

if __name__ == '__main__':
    asyncio.run(main())

额外注意事项

  • IMDbPY是同步库,直接在异步处理器中调用会阻塞事件循环,必须用asyncio.to_thread()将同步调用放到线程池执行。
  • 所有处理器函数必须定义为async def,否则会与异步Application框架冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:47:27