运行 使用 python asyncio 的两个无限任务

Running two infinite tasks with python asyncio

我的程序应该使用用户定义的文本回复用户帐户收到的电报消息。可以通过向电报机器人发送消息来更改此文本。 对于机器人,我一直在使用 PyTelegramBotAPI,而为了从用户帐户发送消息,我一直在使用 Telethon。 我可以通过调用 bot.polling() 运行 机器人,它工作正常。 Telethon 客户端也可以单独工作,它有如下方法:

async def run():
    self.add_event_handler(self.message_handler, events.NewMessage)

    while True:
        #(Every Second the while is supposed to be checked)
        if(condition):
            do_something()

async def message_handler(self, event):
     do_another_thing()

要启动 运行 客户端,我会:

loop = asyncio.get_event_loop()

loop.run_until_complete(client.run())

但我不能同时运行。

我试过:

asyncio.get_event_loop().run_until_complete(asyncio.gather(
    bot.bot.polling(none_stop=True, interval=0.1, timeout=15),
    client.run()
))

到 运行 他们两个同时,但这只是 运行 机器人。

我也试过:

executor = ProcessPoolExecutor(2)
loop = asyncio.get_event_loop()
boo = asyncio.create_task(loop.run_in_executor(executor, bot.bot.polling(none_stop=True, interval=0.5, timeout=15)))
baa = asyncio.create_task(loop.run_in_executor(executor, client.run()))

但是也没用。

能否请您告诉我如何同时 运行 机器人和客户端?

您应该将此代码放在脚本的末尾。

loop = asyncio.get_event_loop()
loop.create_task(function1())
loop.create_task(function2())
loop.run_forever()

问题,如Lonami, was that the PyTelegramBotAPI is not an asynchronous library, therefor when adding it to asyncio event loop, it never gave control back to other tasks, (client.run() method in my case). I switched to aiogram评论中提到的,是一个异步库,问题已解决。

P.S。 PyTelegramBotAPI 提供了一个异步模块,但我无法让它工作。在其 GitHub 页面上提出问题也无济于事。

这对我有用 python-telegram-bot'2 处理程序的异步模式:

from telegram import Bot, Chat
from telegram.ext import Updater, CommandHandler

telegram_bot = Bot(token=token)
telegram_chat = Chat(id=test_group_chat_id, type='group', bot=telegram_bot)
updater = Updater(bot=telegram_bot, use_context=True)
dp = updater.dispatcher

async def main_loop():
    while condition_1:
        # Do stuff
        if condition_2:
            telegram_chat.send_message('Something happened')
        pass

def callback_function(update, context):
    telegram_chat.send_message('Test')

async def main_telegram():
    dp.add_handler(CommandHandler("command", callback_function, run_async=True))
    updater.start_polling()

if __name__ == '__main__':
    
   
    loop = asyncio.get_event_loop()
    try:
        loop.create_task(main_loop(), name="Main loop")
        loop.create_task(main_telegram(), name="Telegram listen task")
        loop.run_forever()
    finally:
        log.info("Shutting down ...")
        log.info("Updater running " + str(updater.running))
        updater.stop()

        pending = asyncio.all_tasks(loop=loop)
        for task in pending:
            task.cancel()
    
        loop.stop()
        loop.close()