两个 Asyncio 同时休眠

Two Asyncio Sleep at the same time

这是我的代码的一个非常恢复的版本,但也可以工作。问题是我想等待 2 秒发送“pong”,同时等待 1 秒将 msgPerSecond 设置为 0。我该怎么做?

msgPerSecond = 0

async def on_message(self, message):
    if message.author == self.user or message.author.bot:
        return

    if message.content == 'ping':
        # Wait 2 seconds to send pong
        await asyncio.sleep(2)
        await message.channel.send('pong')

    msgPerSecond += 1
    print(f'msgPerSecond: {msgPerSecond}')

    # In 1 second reset msgPerSecond 
    await asyncio.sleep(1)
 
    msgPerSecond = 0
    print('msgPerSecond: 0')

我会重组代码,让 msgPerSecond 在它自己的循环中输出,运行 这与 pong 逻辑异步。您可以使用 class 来存储在每个时间间隔内看到的消息数并定期打印该值。

class MessageMetrics:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

    async def report(self):
        while True:
            await asyncio.sleep(1)
            print(f'msgPerSecond: {self.count}')
            self.count = 0

用法示例:

metrics = MessageMetrics()


async def on_message():
    await asyncio.sleep(2)
    metrics.increment()
    await asyncio.sleep(2)
    metrics.increment()
    metrics.increment()
    metrics.increment()
    await asyncio.sleep(2)
    metrics.increment()
    metrics.increment()


async def main():
    metrics_task = asyncio.create_task(metrics.report())
    await on_message()
    await metrics_task


if __name__ == "__main__":
    asyncio.run(main())

打印:

msgPerSecond: 0
msgPerSecond: 1
msgPerSecond: 0
msgPerSecond: 3
msgPerSecond: 0
msgPerSecond: 2
msgPerSecond: 0

我找到了解决方案,以防有人在寻找它

如果您使用的 Python 版本低于 3.7,请使用 asyncio.ensure_future instead of asnycio.create_task

msgPerSecond = 0

async def on_message(self, message):
    if message.author == self.user or message.author.bot:
        return

    if message.content == 'ping':
        asyncio.create_task(send_pong())

    asyncio.create_task(set_MsgPerSecond())

    # Now all the functions with ensure_future method runs at the same time :D

async def send_pong():
    # Wait 2 seconds to send pong
    await asyncio.sleep(2)

    await message.channel.send('pong')

async def set_MsgPerSecond():
    msgPerSecond += 1
    print(f'msgPerSecond: {msgPerSecond}')

    # In 1 second reset msgPerSecond 
    await asyncio.sleep(1)

    msgPerSecond = 0
    print('msgPerSecond: 0')