为何discord.utils.sleep_until在Discord机器人定时任务中无限休眠?
解决discord.py中tasks.loop的before_loop里sleep_until无限休眠问题
你在Cog中定义了每分钟整点执行的定时任务,通过before_loop计算下一分钟整点并调用discord.utils.sleep_until等待,但'sleep done'始终未打印,任务无法正常启动。
问题原因
datetime.datetime.now()获取的是本地时间,而discord.utils.sleep_until要求传入的是UTC时间——discord.py内部所有时间相关逻辑均基于UTC实现。如果你的本地时区和UTC存在偏移,计算出的next_minute会和实际UTC时间不匹配,导致sleep_until进入无限等待状态。
解决方案
将时间计算切换为UTC时间,用datetime.datetime.utcnow()替代datetime.datetime.now(),修改后的代码如下:
import discord from discord.ext import commands from discord.ext import tasks import datetime class Fanfare(commands.Cog): def __init__(self, bot): self.bot = bot self.fanfare.start() @tasks.loop(seconds=60) async def fanfare(self): print('do something') @fanfare.before_loop async def fanfare_before_loop(self): await self.bot.wait_until_ready() # 计算下一分钟的整点时刻(使用UTC时间) now = datetime.datetime.utcnow() next_minute = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1) # 调试打印 print(now) print(next_minute) # 等待到下一分钟 await discord.utils.sleep_until(next_minute) print('sleep done') def setup(bot): bot.add_cog(Fanfare(bot))
补充说明
如果必须基于本地时间处理,也可以给时间对象添加时区信息,确保和discord.utils.sleep_until的要求一致。示例如下:
import pytz # 需要先安装pytz库:pip install pytz # 获取带时区的本地时间 local_tz = pytz.timezone('Asia/Shanghai') # 替换为你的实际时区 now = datetime.datetime.now(local_tz) next_minute = now.replace(second=0, microsecond=0) + datetime.timedelta(minutes=1) # 转换为UTC时间后传入sleep_until next_minute_utc = next_minute.astimezone(pytz.utc) await discord.utils.sleep_until(next_minute_utc)
内容的提问来源于stack exchange,提问作者Mateo Vial
相关产品推荐
相关产品推荐

