【发布时间】:2022-01-14 07:12:16
【问题描述】:
好吧,我有一个 Discord 机器人,在 main.py 中声明如下:
import discord
import asyncio
#
import settingsDB
import logger
#
import module_one
import module_two
import module_three
import module_four
[...]
client = discord.Client()
botToken = settingsDB.getBotSetting("DiscordToken")
# on_ready event stuff
@client.event
async def on_ready():
# stuff
# [...]
# on_message event stuff
@client.event
async def on_message(message):
# stuff
# [...]
# Tasks functions
async def taskOne():
while True:
cycle = settingsDB.getBotSetting("taskOne_Cycle")
# calling for stuff in module_one.py
# stuff
# [...]
await asyncio.sleep(int(cycle))
async def taskTwo():
while True:
cycle = settingsDB.getBotSetting("taskTwo_Cycle")
# calling for stuff in module_two.py
# stuff
# [...]
await asyncio.sleep(int(cycle))
async def taskThree():
while True:
cycle = settingsDB.getBotSetting("taskThree_Cycle")
# calling for stuff in module_three.py
# stuff
# [...]
await asyncio.sleep(int(cycle))
async def taskFour():
while True:
cycle = settingsDB.getBotSetting("taskFour_Cycle")
# calling for stuff in module_four.py
# stuff
# [...]
await asyncio.sleep(int(cycle))
client.run(botToken)
settingsDB 指的是settingsDB.py,其中存储了所有查询我的数据库的函数,并且可以根据通过与 Discord bot 无关的另一个源(通过网站 PHP)更新的用户输入进行更改。
logger 指的是logger.py,我正在将我想要作为日志的内容写入 txt 文件。
在on_ready 事件下我写道:
@client.event
async def on_ready():
print('Logged in as {0.user}'.format(client))
try:
asyncio.ensure_future(taskOne())
asyncio.ensure_future(taskTwo())
asyncio.ensure_future(taskThree())
asyncio.ensure_future(taskFour())
except BaseException as err:
logger.logger('Unexpected error > "' + str(err) + '" / "' + str(type(err)) + '"')
raise
在前几天我已经多次更改这部分,因为我想要真正的异步行为,但无法实现。
但无论我在这里写什么,我注意到几个小时后,4 个任务,甚至机器人本身都是随机启动的,而不是根据await asyncio.sleep(int(cycle))每个task###() 的末尾都有。
最奇怪的部分是机器人本身正在触发print 行,因此告诉我它再次登录(???)
我不得不提一下,taskOne() 可以根据它处理的内容而变化很大,可以从 1 分钟到近 20 分钟不等。
任何想法为什么它会这样?
如果您需要更多详细信息,请告诉我。
在@PythonPro 推荐后,我更改了on_ready 函数:
G_hasLaunched = False
@client.event
async def on_ready():
global G_hasLaunched
print('Logged in as {0.user}'.format(client))
if G_hasLaunched == False:
G_hasLaunched = True
try:
print("creating tasks")
asyncio.ensure_future(taskOne())
asyncio.ensure_future(taskTwo())
asyncio.ensure_future(taskThree())
asyncio.ensure_future(taskFour())
except BaseException as err:
logger.logger('Unexpected error > "' + str(err) + '" / "' + str(type(err)) + '"')
raise
仍在试图弄清楚它是否解决了整个混乱
【问题讨论】:
-
我想提供一些有关何时执行
on_ready()的上下文,它在机器人首次启动或网络中断并且机器人尝试重新连接时执行。那么,是不是发生在网络中断之后呢? -
用
asyncio.create_task代替asyncio.ensure_future怎么样? -
您从数据库中获取的数据也是同步的。他们可以阻止事件循环。
-
@Ratery 起初我使用
client.loop.created_task然后我尝试asyncio.create_task,同样的行为:(
标签: python-3.x discord.py python-asyncio