簡體   English   中英

使用 python asyncio 運行兩個無限任務

[英]Running two infinite tasks with python asyncio

我的程序應該用用戶定義的文本回復用戶帳戶收到的 Telegram 消息。 可以通過向電報機器人發送消息來更改此文本。 對於機器人,我一直在使用 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()))

但它也不起作用。

你能告訴我如何同時運行機器人和客戶端嗎?

正如Lonami在評論中提到的那樣,問題在於 PyTelegramBotAPI 不是一個異步庫,因此在將其添加到 asyncio 事件循環時,它從未將控制權交還給其他任務(在我的例子中是client.run()方法)。 我切換到aiogram ,這是一個異步庫,問題就解決了。

PS 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()

您應該將此代碼放在腳本的末尾。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM