python-telegraph-bot中异步处理的问题

xpcnnkqh  于 2023-01-08  发布在  Python
关注(0)|答案(2)|浏览(140)

我有一个困扰我很久的问题。我将非常感谢你的帮助!
让我们设想这样一种情况:
您通过命令输入了一个函数。在这个特定的函数中,有一个循环需要很长时间才能完成,或者更糟的是,它实际上是一个无限循环。问题是,如何中止这个循环或函数,以便bot可以处理其他请求?
下面是一个例子:

def function(update, context):
  counter = 0
  message = update.message.reply_text(str(counter))

  while True:
    counter += 1
    message = message.edit_text(text = str(counter))
    time.sleep(1)

dispatcher.add_handler(CommandHandler("main", function))

用户通过"/main "进入此功能后,他或她会得到一条包含数字的消息,该数字每秒钟都会增加,这将需要永远的时间才能完成。
我试过的东西:

  • 设计另一个MessageHandler,如果用户发送一些关键字,如"stop",它将更改全局变量的值。在循环中,它将在每次添加数字之前检查该变量是否为True,如果为False,则中断。

但是,在循环实际结束之前,MessageHandler不会检测到该消息,因此这没有意义。

  • 在消息中包含一个InlineKeyboard,带有一个名为"停止"的按钮。设计另一个CallbackQueryHandler来处理这个按钮。

类似地,CallbackQueryHandler只会在循环完成后接收回调,如果我在计数器命中5之类的数字时设置手动break,就可以验证这一点。
我在想,是否可以设计某种异步运行的abort函数,但我个人对Python中的async并不是很熟悉,经过一些尝试,比如设置async defCallbackQueryHandler(query_handle, run_async = True),我仍然没有产生这种效果。
我注意到有一个叫做from telegram.ext.dispatcher import run_async的装饰器,这有帮助吗?或者,有没有其他方法来实现这个结果?
谢谢!

fzsnzjdm

fzsnzjdm1#

默认情况下,Dispatcher会逐个处理传入的更新,这就是为什么前两种方法无法工作的原因,您可以做的是在一个独立的线程中运行循环,实际上,run_async参数的作用是什么-它与asyncio编程无关。请参阅此wiki页面以了解关于run_async的详细信息。还请注意,PTB的下一个主要版本将向PTB引入asyncio-请参见this announcement
我想指出的是while循环+time.sleep()可能不是最好的主意,特别是如果睡眠时间很长的话,另一种选择是调度一个重复的作业,PTB有内置的JobQueue可以做到这一点。
免责声明:我目前是python-telegram-bot的维护者。

qxsslcnc

qxsslcnc2#

示例如何为python-telegram-bot==13.13配置在任何nc模式下运行的处理程序(run_async=True传递给处理程序):

dispatcher.add_handler(CommandHandler(["zip_and_send_all_logs", "zsal"],
                                      zip_and_send_all_logs_cmd, run_async=True))
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command,
                                      run_sh_cmd_for_text_msg, run_async=True))

中还有@run_async装饰器函数

from telegram.ext.dispatcher import run_async

它可以用来标记处理程序以异步模式运行。但是这个装饰器被弃用。推荐的方法是将run_async参数传递给处理程序。它的默认值是False
相关问题:Is python-telegram-bot suitable for async job? #877

相关问题