首页 > 解决方案 > 为什么在等待异步队列时 discord.py 会阻塞/缓冲?

问题描述

消息以“波”的形式发送,即几秒钟内什么都没有,然后几乎同时发送~5 次。我遗漏了tokenchannel

import discord, asyncio

class Bot(discord.Client):
    def __init__(self, q, channel):
        super().__init__()
        self.q = q
        self.channel_id = channel
        self.bg_task = self.loop.create_task(self.send_messages())

    async def on_message(self, message):
        if message.author == self.user or message.channel.id != self.channel_id:
            return
        print(message.content)

    async def send_messages(self):
        await self.wait_until_ready()
        channel = self.get_channel(self.channel_id)
        while not self.is_closed():
            msg = await self.q.get()
            await channel.send(msg)

from threading import Thread
from time import sleep

q = asyncio.Queue()
def f():
    while True:
        q.put_nowait("hi")
        sleep(2)
Thread(target=f).start()

bot = Bot(q, channel)
bot.run(token)

奇怪的是,该on_message事件似乎没有受到影响,而且,替换msg = await self.q.get()

msg = "hi"
await asyncio.sleep(2)

似乎导致了预期的行为。

我不确定哪里出了问题,所以我把这个例子更具体地放在了 Discord 上。

编辑

扩展asyncio.sleep行为,我已将循环替换send_messages

if 0:
    msg = await self.q.get()
else:
    await asyncio.sleep(0.1)
    if self.q.empty():
        continue
    msg = await self.q.get()
await channel.send(msg)

if只是在原始和实验之间切换。

显然,人们希望该else部分最多与该部分一样快if,但是等待队列非空似乎可以完全解决问题。

我开始认为不和谐和阻塞异步队列以不可预见的方式交互

另一方面,似乎channel.send是阻塞线,所以也许它也与速率有关。

标签: pythonpython-3.xpython-asynciodiscord.py

解决方案


这是因为通过 Discord 的 API 发送消息的速率限制为 5 / 5 秒。
这就是为什么您会看到一次发送 5 条消息,然后由于下一条消息的速率受限而延迟。


推荐阅读