如何在discord.py中取消asyncio.sleep命令

时间:2020-03-11 21:39:21

标签: asynchronous discord python-asyncio sleep discord.py

我的机器人中有一个计时器命令,它使用asyncio.sleep。如果用户希望取消命令,我想发出一条命令。

@bot.command()
async def timer(ctx, time: int):
   await ctx.send('Timer set for ' + str(time) + ' seconds')
   await asyncio.sleep(time)
   await ctx.send('Time over!')

有没有办法做到这一点(我不喜欢一种不创建新文件的方法,请在同一文件中执行此操作)

1 个答案:

答案 0 :(得分:0)

引用Interrupt all asyncio.sleep currently executing

获得https://stackoverflow.com/users/2846140/vincent的异步代码。

您可以添加此功能(由Vincent提供):

def make_sleep():
    async def sleep(delay, result=None, *, loop=None):
        coro = asyncio.sleep(delay, result=result, loop=loop)
        task = asyncio.ensure_future(coro)
        sleep.tasks.add(task)
        try:
            return await task
        except asyncio.CancelledError:
            return result
        finally:
            sleep.tasks.remove(task)

    sleep.tasks = set()
    sleep.cancel_all = lambda: sum(task.cancel() for task in sleep.tasks)
    return sleep

在这种情况下的用法是:

@bot.command()
async def timer(ctx, time: int):
   await ctx.send('Timer set for ' + str(time) + ' seconds')
   await sleep(time)
   await ctx.send('Time over!')

@bot.command()
async def canceltimers(ctx):
    sleep.cancel_all()
    await asyncio.wait(sleep.tasks)
    await ctx.send('Timers cancelled')

bot.run(token)放在sleep = make_sleep()之前的位置,否则将不起作用。

现在,我们现在面临的问题是这段代码;我们取消所有计时器;这当然不是我们想要的,因为会有明显的冲突。您如何才能做到这一点完全取决于您自己;但是您可以尝试在睡眠功能中添加一个由userID存储的标识符。确实由您决定,但这是背后的理论和基本代码。