我有一个困扰我很久的问题。我将非常感谢你的帮助!
让我们设想这样一种情况:
您通过命令输入了一个函数。在这个特定的函数中,有一个循环需要很长时间才能完成,或者更糟的是,它实际上是一个无限循环。问题是,如何中止这个循环或函数,以便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 def
或CallbackQueryHandler(query_handle, run_async = True)
,我仍然没有产生这种效果。
我注意到有一个叫做from telegram.ext.dispatcher import run_async
的装饰器,这有帮助吗?或者,有没有其他方法来实现这个结果?
谢谢!
2条答案
按热度按时间fzsnzjdm1#
默认情况下,
Dispatcher
会逐个处理传入的更新,这就是为什么前两种方法无法工作的原因,您可以做的是在一个独立的线程中运行循环,实际上,run_async
参数的作用是什么-它与asyncio
编程无关。请参阅此wiki页面以了解关于run_async
的详细信息。还请注意,PTB的下一个主要版本将向PTB引入asyncio
-请参见this announcement。我想指出的是
while
循环+time.sleep()
可能不是最好的主意,特别是如果睡眠时间很长的话,另一种选择是调度一个重复的作业,PTB有内置的JobQueue
可以做到这一点。免责声明:我目前是
python-telegram-bot
的维护者。qxsslcnc2#
示例如何为
python-telegram-bot==13.13
配置在任何nc模式下运行的处理程序(run_async=True
传递给处理程序):中还有
@run_async
装饰器函数它可以用来标记处理程序以异步模式运行。但是这个装饰器被弃用。推荐的方法是将
run_async
参数传递给处理程序。它的默认值是False
。相关问题:Is python-telegram-bot suitable for async job? #877