关于python电报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;"停止";,它会更改全局变量的值。在循环中,每次添加数字之前,它都会检查这个变量是否为True,如果是False,它就会中断。

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

  • 在消息中包括InlineKeyboard;停止";。设计另一个CallbackQueryHandler来处理这个按钮。

    类似地,CallbackQueryHandler将只在循环完成后接收回调。如果我在计数器达到5之类的数字时设置手动break,这可以得到验证。

我在想是否可以设计某种异步运行的中止函数,但我个人对Python中的异步不太熟悉。经过一些试验,比如设置async defCallbackQueryHandler(query_handle, run_async = True),我仍然没有产生这种效果。

我注意到有一个名为from telegram.ext.dispatcher import run_async的装饰器,这有帮助吗?或者,还有其他方法可以实现这个结果吗?

谢谢!

默认情况下,Dispatcher逐个处理传入的更新。这就是为什么你的前两种方法不起作用。您可以做的是在一个独立的线程中运行循环。事实上,这就是run_async参数的作用——它与asyncio编程无关。有关run_async的详细信息,请参阅此wiki页面。还要注意的是,PTB的下一个主要版本将向PTB引入asyncio——请参阅本公告。

我想指出的是,while循环+time.sleep()可能不是最好的主意,尤其是在睡眠时间很长的情况下。另一种选择是安排重复作业。PTB内置了JobQueue


免责声明:我目前是python-telegram-bot的维护者。

示例如何为python-telegram-bot==13.13配置在anync模式下运行的处理程序(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

相关问题:python电报机器人适合异步作业吗#877

最新更新