首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python aiogram如何停止异步循环

python aiogram如何停止异步循环
EN

Stack Overflow用户
提问于 2020-10-21 03:59:41
回答 2查看 870关注 0票数 0

简单的例子

代码语言:javascript
复制
import asyncio
import logging
from aiogram import Bot, Dispatcher, types


logging.basicConfig(level=logging.INFO)
token = 'token'

bot = Bot(token=token)
dp = Dispatcher(bot=bot)
@dp.callback_query_handler(text='stoploop')
async def stop_loop(query: types.CallbackQuery):
    #  TODO how to stop test loop?

    await query.message.edit_text('stop')


@dp.callback_query_handler(text='test')
async def start_loop(query: types.CallbackQuery):
    a = 100
    while True:
        a -= 1
        markup = types.InlineKeyboardMarkup()
        markup.add(types.InlineKeyboardButton('<<<Stop And Back To Home', callback_data='stoploop'))
        await query.message.edit_text(str(a),reply_markup=markup)
        await asyncio.sleep(1)


@dp.message_handler(commands='start')
async def start_cmd_handler(message: types.Message):
    markup = types.InlineKeyboardMarkup()
    markup.add(
        types.InlineKeyboardButton('start loop', callback_data='test')
    )
    await message.reply('test', reply_markup=markup)


async def main():
    try:
        await dp.start_polling()
    finally:
        await bot.close()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

当我单击start_loop时,页面上的tg消息框开始显示倒计时。当我单击停止时,我如何停止前面的倒计时?我使用id( query )来确认发送两次的查询实例不同。在我执行了stop_loop函数之后,start_loop仍然会执行并更改消息的内容。谁能告诉我怎么阻止它?

EN

回答 2

Stack Overflow用户

发布于 2020-10-21 15:52:01

我用redis解决了这个问题,但我不知道这是不是最合适的方法。如果有更合适的方法,请让我知道。

票数 0
EN

Stack Overflow用户

发布于 2020-11-10 17:08:17

为了管理你的循环,你应该把它放在处理程序之外,直接从任何存储器中获取(例如,dict就是这样)。

循环的基本示例

代码语言:javascript
复制
loops = {}


class Loop:
    def __init__(self, user_id):
        self.user_id = user_id
        self._active = False
        self._stopped = True
        loops[self.user_id] = self
    
    @classmethod
    def get_loop(cls, user_id):
        return loops.get(user_id, cls(user_id))

    @property
    def is_running(self):
        return not self._stopped
        
    async def start(self):
        self._active = True
        asyncio.create_task(self._run_loop())
        
    async def _run_loop(self):
        while self._active:
            await bot.send_message(self.user_id, 'loop is running')
            await asyncio.sleep(5)
        self._stopped = True
    
    async def stop(self):
        self._active = False
        while not self._stopped:
            await asyncio.sleep(1)

那么:

代码语言:javascript
复制
@dp.callback_query_handler(text='start')
async def start_loop(query: CallbackQuery):
    user = query.from_user
    loop = Loop.get_loop(user.id)
    
    if loop.is_running:
        return await query.answer('Loop is already running')
    
    loop.start()
    await query.answer('Started!')


@dp.callback_query_handler(text='stop')
async def stop_loop(query: CallbackQuery):
    user = query.from_user
    loop = Loop.get_loop(user.id)
    await query.answer('Stopping...')
    await loop.stop()
    await bot.send_message(user.id, 'Loop successfully stopped.')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64452503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档