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

Pyrogram上传取消异常:点击内联按钮无法终止上传求助

问题根源

类内部使用@app.on_callback_query()装饰方法是错误用法:Pyrogram的装饰器会将回调绑定到app实例,而非uploader的实例。点击Cancel时修改的self.is_cancelled并非当前正在执行上传任务的实例属性,因此上传不会终止。同时原进度函数每10秒才检查一次取消状态,会导致取消操作延迟生效。

解决方法

1. 全局字典跟踪上传实例

在文件顶部定义全局字典,用于存储当前活跃的上传任务实例(以用户ID为键,单用户单任务场景适用):

active_uploads = {}

2. 修改uploader类的start方法

在任务启动时将实例存入字典,任务结束(成功/失败/取消)时移除:

async def start(self, from_user_id, filepath, reply, thum, caption, message=""):
    try:
        # 注册当前上传实例
        active_uploads[from_user_id] = self
        thum = Path(thum)
        if not thum.is_file():
            thum = None
        # 原有上传逻辑保持不变...
    except Exception:
        ers = traceback.format_exc()
        await channel_log(ers)
        LOGS.info(ers)
    finally:
        # 任务结束后移除实例
        if from_user_id in active_uploads:
            del active_uploads[from_user_id]

3. 类外定义回调函数,关联全局实例

将回调移出类,通过全局字典获取对应上传实例并标记取消:

@app.on_callback_query()
async def button_callback(callback_query):
    if callback_query.data == "cancel_upload":
        user_id = callback_query.from_user.id
        if user_id in active_uploads:
            # 标记对应任务为取消状态
            active_uploads[user_id].is_cancelled = True
            await callback_query.answer("上传已取消")

4. 优化进度函数的取消检查

将取消检查改为每次进度更新都执行,确保取消操作即时生效:

async def progress_for_pyrogram(self, current, total, bot, ud_type, message, start):
    now = time.time()
    diff = now - start
    
    # 每次进度更新都检查是否取消
    if self.is_cancelled:
        bot.stop_transmission()
        await message.edit_text("`Uploading Cancelled.`")
        return
    
    # 原有进度更新逻辑保持不变...

额外说明

  • 若允许单用户多任务,需改用上传任务对应的消息ID(如reply.message_id)作为字典键,确保每个任务对应唯一实例。
  • 务必在所有任务结束路径中移除字典内的实例,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:47:54