我的机器人中有一个计时器命令,它使用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!')
有没有办法做到这一点(我不喜欢一种不创建新文件的方法,请在同一文件中执行此操作)
答案 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存储的标识符。确实由您决定,但这是背后的理论和基本代码。