在python-telegram-bot库中,默认情况下按顺序处理请求。
对于并行工作,使用了一个装饰器@run_async,它必须添加到所有处理函数中,例如:
import threading
from telegram import Update
from telegram.ext import Updater, MessageHandler, Filters, CallbackContext
from telegram.ext.dispatcher import run_async
@run_async
def on_request(update: Update, context: CallbackContext):
message = update.effective_message
message.reply_text(f'Thread: {threading.current_thread()}')
if __name__ == '__main__':
updater = Updater(TOKEN)
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.text, on_request))
updater.start_polling()
updater.idle()
但是从版本13开始,装饰器已被弃用,而是库提供在处理程序中使用同名参数Handler或通过方法运行函数Dispatcher.run_async(这有点不同):
TelegramDeprecationWarning: The @run_async decorator is deprecated. Use the `run_async` parameter of your Handler or `Dispatcher.run_async` instead.
return self.callback(update, context)
使用参数run_async=True有效:
import threading
from telegram import Update
from telegram.ext import Updater, MessageHandler, Filters, CallbackContext
def on_request(update: Update, context: CallbackContext):
message = update.effective_message
message.reply_text(f'Thread: {threading.current_thread()}')
if __name__ == '__main__':
updater = Updater(TOKEN)
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.text, on_request, run_async=True))
updater.start_polling()
updater.idle()
但是切换到参数run_async=True而不是装饰器存在问题@run_async
毕竟,您需要在所有受支持的机器人中执行以下操作:
- 删除装饰器导入
from telegram.ext.dispatcher import run_async - 删除
@run_async所有处理函数中的装饰器 - 为所有处理程序指定一个参数
run_async=True- 顺便说一句,这也适用于添加错误处理程序Dispatcher.add_error_handler的方法
有些机器人可以有大约 50 个处理程序。每个处理程序指定该参数的成本很高。当然,你可以离开旧版本,但是如果你想更新版本,那么你可以在这里做什么呢?
如何不那么痛苦地切换到机器人的异步模式?
PS。
可以通过线程的名称来理解单独线程中的处理函数,当f'Thread: {threading.current_thread()}'.
这里没有线程:
Thread: <Thread(Bot:{id бота}:dispatcher, started 772)>
而这个在流中:
Thread: <Thread(Bot:{id бота}:worker:a36abf98-33a8-4c73-8c02-51a3e5241b5e_0, started 26488)>
首先想到的是遍历所有处理程序并强制它们
run_async = True:有用
但是这样的解决方案是拐杖,有更好的方法
该库有一个Defaults类(在我看来,它只是从版本 13 开始出现的),这个类有一个字段
run_async,并且可以将一个类对象传递给机器人设置。除了使用Defaults是官方 API 之外,它还会影响默认值,例如,如果某些情况下不需要异步处理,那么您可以在 handler 中指定 this,安装时不会更改
Defaults(run_async=True),与上面的方法不同:例子: