@tasks.loop() 停止命令运行直到循环完成

时间:2021-05-10 22:35:40

标签: python asynchronous discord.py

我有一个涉及 selenium 的后台循环,所以需要很长时间才能完成执行。我注意到机器人在响应命令时有延迟,我发现 @tasks.loop() 中的进程需要在命令执行之前完成。例如:

from discord.ext import commands, tasks
import time

bot = commands.Bot(command_prefix='-')

@bot.command()
async def test(ctx):
    await ctx.send('hi')

@tasks.loop(seconds=30)
async def loop():
    print('h')
    time.sleep(20)
    print('i')


@bot.event
async def on_ready():
    loop.start()

bot.run()

在这里,如果您在打印字母 h 之后和打印字母 i 之前执行 -test,机器人将不会响应,直到它打印i 循环结束。

我如何才能使命令能够与循环一起执行?仅供参考,我的代码没有 time.sleep(),这只是一个示例。

1 个答案:

答案 0 :(得分:1)

如果您有长时间运行的代码,那么您应该将其移动到单独的函数中并使用 threading 或`multiprocessing 运行它。

这里是带有 threading 的基本示例。它在每个循环中运行新线程。对于更复杂的东西,它可能需要不同的方法。可能需要在discord之前运行单线程,并在queue中使用loop向线程发送信息。

from discord.ext import commands, tasks
import time
import threading
import os

bot = commands.Bot(command_prefix='-')

@bot.command()
async def test(ctx):
    await ctx.send('hi')

def long_running_function():
    print('long_running_function: start')
    time.sleep(10)
    print('long_running_function: end')
    
@tasks.loop(seconds=30)
async def loop():
    print('h')
    t = threading.Thread(target=long_running_function)
    t.start()
    print('i')

@bot.event
async def on_ready():
    loop.start()

bot.run(os.getenv('DISCORD_TOKEN'))