【问题标题】:Discord.py on_message event handler is blockingDiscord.py on_message 事件处理程序被阻塞
【发布时间】:2022-01-06 01:21:46
【问题描述】:

我注意到 on_message 事件处理程序一次只能处理 1 条消息。

所以当我们需要在其中处理一些耗时的任务时,它实际上会阻止机器人处理稍后进来的消息。

在下面的示例中,如果用户快速连续发送两条或多条消息,机器人将拾取第一条消息并开始处理它,但它不会处理第二条消息,直到它完成第一条消息并且将结果发回,在这种情况下,说执行该 get_result_from_time_sumption_task 函数需要几分钟。它实际上会在执行此操作时阻止所有传入消息。

我试图实现多线程来处理耗时的任务,但是在玩了之后,我无法让消息发送与它一起工作。

@client.event
async def on_message(message):
   result = get_result_from_time_consuming_task()
   sent_message = await message.channel.send(result)

【问题讨论】:

  • 通过适当的异步代码,on_message 将能够同时处理多条消息。 get_result_from_time_consuming_task() 很可能是阻塞的,您将把它重写为异步的。如果你不能将它重写为异步,那么你可以把它放在一个线程中。参见示例here

标签: python discord.py


【解决方案1】:

你可以使用asyncio.create_task(a_coroutine(message.channel)),这行代码将是非阻塞的,所以该函数将准备好在下一条消息时再次调用

你的协程会是这样的

async def a_coroutine(channel):
    result = get_result_from_time_consuming_task()
    sent_message = await channel.send(result)

如果这不起作用,也许你应该开始研究 Cogs https://discordpy.readthedocs.io/en/latest/ext/commands/cogs.html#ext-commands-cogs

我还有一个不和谐的机器人,它的 on_message 行为非常复杂,但是当两条消息尽可能快地发送时,仍然会为这两条消息触发 on_message 的行为(它会为每条消息添加 2 个反应,并且它会第一反应第一消息,第二反应,第二反应第一和第二反应第二)所以我认为这可能是由于@client.event@commands.Cog.listener() 相比的不同实现

【讨论】:

  • 我尝试了你的解决方案,但是协程函数仍然阻止处理传入的消息。
  • 我已经编辑了我的答案@Jerry
【解决方案2】:

我最终这样做是为了避免阻塞异步和等待代码

async def on_message(message):
   thread = threading.Thread(target=perform_time_consuming_task, args=(message,))
   thread.start()

def perform_time_consuming_task(message):
   # slow code here
   client.loop.create_task(message.channel.send("your result"))

【讨论】:

    猜你喜欢
    • 2021-09-24
    • 2012-04-11
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2022-01-16
    • 2021-11-16
    相关资源
    最近更新 更多