【问题标题】:Sending messages from a thread in a Python Discord bot从 Python Discord 机器人中的线程发送消息
【发布时间】:2023-04-03 03:25:01
【问题描述】:

我正在使用 discord.py 库并正在开发一个 discord 机器人。

基本上,我需要我的机器人每小时访问一个网站并获取一些有关 selenium 的信息。 我想在一个线程中执行此操作以避免在信息收集期间阻塞机器人。

@tasks.loop(hours=1)
async def getwebsiteinfo(self):
    thr = threading.Thread(target=self.getwebsiteinfofunc)
    thr.start()

获取网站信息功能:

def getwebsiteinfofunc(self):
...
channel.send(f"```sometext```")
..

问题是:channel.send 需要用 await 调用,但我不能用 await 调用它,因为它不在异步函数中。

但我不能将 getwebsiteinfofunc 定义为异步,因为我不能将异步函数与线程一起使用。

我尝试了 asyncio,但我从未使用过它并且失败了。

有什么想法吗?

【问题讨论】:

  • here
  • 我不能使用 loop.run_in_executor 因为我应该在哪里调用它?如果我在班级的初始化中调用它,它不是异步的
  • 请记住,我需要它在循环中运行它不是等待一段时间的一次性命令
  • 您可以在异步函数中使用 result = await loop.run_in_executor(ThreadPoolExecutor(), self.getwebsiteinfofunc) 而不是 thr = threading.Thread(target=self.getwebsiteinfofunc)。然后您可以在异步函数中调用await channel.send(result)。如果您需要这些特定代码,请使用minimal, reproducible example 更新您的问题(可以按原样运行的代码,而不仅仅是 sn-ps)。

标签: python asynchronous async-await bots discord.py


【解决方案1】:

如果您以异步方式编写整个任务,它不会阻塞机器人的其余部分,asyncio 本身允许您编写并发任务而无需线程。

许多同步库都有 aio 替代方案,例如,使用 aiohttp Client 代替 requests 库。

【讨论】:

  • 我的整个任务已经处于异步状态(我使用了@tasks.loop 和异步定义)但它阻止了机器人,我测试了它试图在任务进行时发送另一个命令而机器人没有一直回复到任务完成。我是初学者,所以我不知道如何从非异步函数开始任务
  • 您的任务中有一些东西正在执行同步操作,从我上面的示例继续,如果您在任务中使用requests,它将阻塞事件循环直到它完成。
  • 我使用 selenium,这就是为什么我首先使用线程,有没有办法解决这个仍然使用 selenium?
  • 我一眼就能找到最接近的是github.com/HDE/arsenic。你也可以尝试使用run_in_executor 来运行你的阻塞硒操作
猜你喜欢
  • 2019-07-22
  • 2021-08-19
  • 2021-01-08
  • 2021-10-29
  • 2020-11-23
  • 2021-02-22
  • 2019-09-12
  • 2021-08-27
  • 1970-01-01
相关资源
最近更新 更多