首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为并发处理的命令创建函数

如何为并发处理的命令创建函数
EN

Stack Overflow用户
提问于 2021-11-20 05:01:36
回答 2查看 54关注 0票数 0

当我在不和谐中键入命令!sleeper时,然后紧接着键入!hello。机器人基本上处于暂停10秒,因为它正在处理!sleeper。在10秒之后,它发送消息I have been sleeping for 10 seconds,然后紧接着发送Hello partner!。如果有人发送!sleeper命令,我如何才能使整个机器人不被“暂停”。

现在发生了什么:

  1. I型!sleeper
  2. I型!hello
  3. 机器人等待9-10秒
  4. Bot发送I have been sleeping for 10 seconds
  5. Bot发送Hello partner!

我想要的:

  1. I型!sleeper
  2. I型!hello
  3. Bot发送Hello partner!
  4. 机器人等待9-10秒
  5. Bot发送I have been sleeping for 10 seconds

PS:我写了“等待9-10秒”,因为输入!hello需要大约一秒钟的时间。

代码语言:javascript
运行
复制
import time

from discord.ext import commands


class Hello(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.Cog.listener()
    async def on_ready(self):
        print(f'{self.__class__.__name__} Cog is ready')

    @commands.command()
    async def hello(self, ctx):
        await ctx.send('Hello partner!')

    @commands.command()
    async def sleeper(self, ctx):
        await self.sleep_now()
        await ctx.send('I have been sleeping for 10 seconds')

    async def sleep_now(self):
        time.sleep(10)

def setup(client):
    client.add_cog(Hello(client))
EN

回答 2

Stack Overflow用户

发布于 2021-11-21 12:11:30

根据您对凯尔答案的评论,您希望异步处理一个函数。

那么,您要实现的是一个线程。您可以创建一个线程并在线程内睡眠10秒(或者执行您的时间开销很大的任务),然后打印“我已经睡了10秒了”。因此,它不会阻止执行!hello和其他命令。它看起来会像这样

这将是昂贵的任务的功能。

代码语言:javascript
运行
复制
async def thread_function(ctx):
    time.sleep(10)
    await ctx.send('I have been sleeping for 10 seconds')

你会这样称呼它

代码语言:javascript
运行
复制
 x = threading.Thread(target= thread_function, args=(ctx))

或者,您可以使用一个事件循环,这是一个更高级的主题。如果需要,您可以研究它,但是它实际上是计算运行时调用的函数,并独立执行它,而不创建新线程。我强烈鼓励你去看看。尽管如此,这是它可能的样子。

代码语言:javascript
运行
复制
from concurrent.futures import ThreadPoolExecutor
loop = asyncio.get_event_loop()
_executor = ThreadPoolExecutor(1)
await loop.run_in_executor(_executor, thread_function, ctx)
票数 1
EN

Stack Overflow用户

发布于 2021-11-20 07:34:24

您可以尝试使用后台任务来实现这一点。我不确定这是最好的还是最干净的解决方案,但是您可以找到更多的文档这里

代码语言:javascript
运行
复制
from discord.ext import tasks, commands


class Hello(commands.Cog):
    def __init__(self, client):
        self.client = client
        # flag variable to keep track of if we are waiting for a response from sleeper
        self.sleeping = 0

    @commands.Cog.listener()
    async def on_ready(self):
        print(f'{self.__class__.__name__} Cog is ready')

    @commands.command()
    async def hello(self, ctx):
        await ctx.send('Hello partner!')

    @commands.command()
    async def sleeper(self, ctx):
        # if the task is already running, ie. someone already called sleeper
        # you cannot start a background task if it is already running, it will cause an error
        if self.sleep.is_running():
            await ctx.send('Already sleeping!')
        else:
            # start the background task
            self.sleep.start(ctx)

    # The loop runs 2 times
    # It runs immediately when you start the task (when you type !sleeper) and then again in increments of the time specified
    # I use a flag to check when to send the message and cancel the task (after the first ten seconds)
    # cancelling the task stops it from sending additional messages every ten seconds
    @tasks.loop(seconds=10.0)
    async def sleep(self, ctx):
        # helper method to stop the background task right after it sends the message
        async def stop_sleep():
            self.sleep.cancel()
        # checks to see if the task is sleeping or not
        if self.sleeping == 1:
            # reset the value
            self.sleeping = 0
            # send the message
            await ctx.send('I have been sleeping for 10 seconds')
            # stop the task
            await stop_sleep()
        else:
            # keep track of it sleeping
            self.sleeping = 1


def setup(client):
    client.add_cog(Hello(client))

编辑:

有一个更好的方法来解决你的问题,而不用背景任务。使用异步而不是睡眠时间。

代码语言:javascript
运行
复制
from discord.ext import commands
import asyncio

class Hello(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.Cog.listener()
    async def on_ready(self):
        print(f'{self.__class__.__name__} Cog is ready')

    @commands.command()
    async def hello(self, ctx):
        await ctx.send('Hello partner!')

    @commands.command()
    async def sleeper(self, ctx):
        await asyncio.sleep(10)
        await ctx.send('I have been sleeping for 10 seconds')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70043360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档