Как остановить asyncio.sleep в дискорд боте

У меня есть дискорд бот, который должен каждый определённый промежуток времени отправлять сообщение в чат и он прекрасно с этим справляется, но теперь я не могу его остановить. Как мне это сделать?

Код:

@bot.command()
async def task(ctx, arg):
    t = False
    i = 0
    if arg == 'on':
        t = True
    elif arg == 'off':
        t = False
    else:
        await ctx.send('Error!')
    while t == True:
        i += 1
        await ctx.send(i)
        await asyncio.sleep(10)

Пытался создать bot.loop.create_task(task(ctx, arg)) как это показано в одном из примеров, но моя функция требует ctx и arg которые есть только внутри команды.


Ответы (1 шт):

Автор решения: eri
async def task_periodic(ctx, arg):
    i = 0
    while True:
        i += 1
        await ctx.send(i)
        await asyncio.sleep(10)

@bot.command()
async def task(ctx, arg):
    if arg == 'on':
        ctx.periodic = bot.loop.create_task(task_periodic(ctx, arg))
    elif arg == 'off':
        if hasattr(ctx,'periodic'):
            ctx.periodic.cancel()
        else:
            ctx.send('first send on')
    else:
        await ctx.send('Error!')

пробуй что-то в этом ключе.

При вызове .cancel() в операции с await произойдет исключение CancelledError, и цикл грохнется.

Желательно ещё сделать обработку исключений после отмены:

try:
    await ctx.periodic
except ...:
    ....

но и без этого исключение не рушит основной цикл.

→ Ссылка