使用Discord进行多线程(计划作业)

时间:2018-10-08 09:44:24

标签: python python-asyncio discord discord.py

首先,道歉。我对Python很陌生。我来自Java / C#编码背景。我在很多方面都喜欢Python的简单性,但同时也发现很难确定一些标准。

例如,我已经成功地使Discord Bot运行。异步方法运行良好。但是我想安排一份工作,每30分钟运行一次。但是,当我键入asyncio.run(job())时,Python告诉我“运行”不是asyncio的属性。我真的不确定为什么会这样说。哎呀,异步是做到这一点的“正确”方法吗?

不和谐的导入是否可能以某种方式掩盖了它?我想我可能需要读书或其他东西!

再次感谢。我确实尝试过搜索,但是什么都没有!

2 个答案:

答案 0 :(得分:2)

random_order_idx = np.random.permutation(np.arange(len(dups))) random_dups_deduped = dups.iloc[random_order_idx].drop_duplicates() pd.concat([uniques, random_dups_deduped]) a dup_flag 0 0 False 1 1 False 3 3 False 6 5 False 7 6 False 5 4 True 2 2 True 在启动discord bot时被调用,因此一种方法是将您的作业附加到它:

on_ready

import discord import asyncio client = discord.Client() @client.event async def on_ready(): while True: await asyncio.sleep(30*60) # every 30 minutes job() client.run(os.environ.get('DISCORD_BOT_SECRET')) # provide your API token here!! non-blocking 睡眠-如果在此处使用asyncio.sleep,则漫游器将等待time.sleep完成,并会对任何传入的其他消息无响应。但是time.sleep所做的是将控制权返回到事件循环,该事件循环可以处理其他机器人功能。只有在30分钟之后,控制权才会返回到await asyncio.sleep

请注意,作业运行时会阻止您的漫游器,这对于任务时间超过几秒钟的作业来说是一个问题。如果您的工作是基于I / O的(例如,获取网站),则可以使用异步I / O操作(例如aiohttp)来保持响应。如果您的作业是基于CPU的,则您可以使用多个进程,例如on_ready,前提是可以使用终端命令来调用您的作业。

答案 1 :(得分:0)

每30分钟安排一次作业的现代方法是使用discord.ext.tasks

import asyncio
import contextlib
import discord
from discord.ext import tasks

client = discord.Client()

@tasks.loop(minutes=30)  # every 30 minutes
async def job():
    with contextlib.suppress(Exception):
        ...  # your code here

job.start()
client.run(os.environ.get('DISCORD_BOT_SECRET'))  # provide your API token here!!

Discord客户端的事件循环每30分钟调用一次函数job()。这里有几点注意事项:

  • 如果job()引发异常,整个循环将停止。是的,不仅是此调用,而且整个循环都将退出。这就是为什么我添加了一个with语句来捕获所有异常的原因,这等效于try: ... except: pass
  • job()正在运行时,机器人的其他部分也被阻止。。这是因为异步不是使用多个线程实现的,而是在单个线程中使用协程的。解决此问题的一种方法可能是使您的代码异步(例如,使用aiohttp进行Web请求)或使用subprocess.Popen启动另一个进程。