首页 > 解决方案 > @tasks.loop() 停止命令运行,直到循环完成

问题描述

我有一个涉及硒的后台循环,因此需要很长时间才能完成执行。我注意到机器人在响应命令时有延迟,我发现里面的进程@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()

在这里,如果您-test在打印字母h之后和打印字母i之前执行此操作,机器人将不会响应,直到它打印i并且循环完成。

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

标签: pythonasynchronousdiscord.py

解决方案


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

这里是基本的例子threading。它在每个循环中运行新线程。对于更复杂的事情,它可能需要不同的方法。它可能需要在之前运行单线程discord并使用queueinloop将信息发送到线程。

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'))

推荐阅读