安排Asyncio任务每X秒执行一次?

时间:2019-01-11 20:03:41

标签: python discord python-asyncio

我正在尝试创建一个python discord机器人,该机器人将每隔X秒检查一次活跃成员,并为他们的在线时间奖励积分。我正在使用asyncio处理聊天命令,并且一切正常。我的问题是找到一种方法来安排每隔X秒使用异步对活动成员进行一次检查

我已经阅读了asnycio文档,但这是我第一次使用它,我很难把头放在任务,循环和协例程等上。

@client.event
async def on_message(message):

    # !gamble command
    if message.content.startswith('!gamble'):

        ...code that works....

    # !help command
    elif message.content == '!help':

         ...code that works....

    # !balance command
    elif message.content == '!balance':

      ...code that works....

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

//Do this every X seconds to give online users +1 points
async def periodic_task():
      TODO

我的目标是使机器人能够处理通过聊天发送给它的命令,同时每隔X秒触发一次与Discord服务器中的聊天命令或事件无关的功能。我知道如何使函数中的代码实现我的目标,而不是如何触发

2 个答案:

答案 0 :(得分:7)

如果您想确保执行时间不会导致间隔漂移,您可以使用 asyncio.gather。

import asyncio, time, random


start_time = time.time()


async def stuff():
    await asyncio.sleep(random.random() * 3)
    print(round(time.time() - start_time, 1), "Finished doing stuff")


async def do_stuff_periodically(interval, periodic_function):
    while True:
        print(round(time.time() - start_time, 1), "Starting periodic function")
        await asyncio.gather(
            asyncio.sleep(interval),
            periodic_function(),
        )


asyncio.run(do_stuff_periodically(5, stuff))

输出变为:

0.0 Starting periodic function
0.5 Finished doing stuff
5.0 Starting periodic function
7.2 Finished doing stuff
10.0 Starting periodic function
10.1 Finished doing stuff
15.0 Starting periodic function
17.9 Finished doing stuff

如您所见,所调用的周期函数的执行时间不会影响新间隔的开始时间。

答案 1 :(得分:3)

async def do_stuff_every_x_seconds(timeout, stuff):
    while True:
        await asyncio.sleep(timeout)
        await stuff()

并将其添加到循环中。

task = asyncio.create_task(do_stuff_every_x_seconds(10, stuff))

当您不再想要这样做时,

task.cancel()
相关问题