运行 一个函数阻止了机器人 - discord.py
Running a function blocks the bot - discord.py
我试图使用在 discord 上键入的命令从四个文件(它们有 4GB 大)中搜索数据。
搜索功能的执行时间需要十分钟左右,遍历4个文件;当我尝试连续键入命令两次时,第二个命令在第一个命令执行后执行(大约 10 分钟后)。
def main(self):
@self.client.command()
async def fsearch(ctx, *args):
self.client.loop.create_task(self.searchTask(ctx, *args))
self.searchTask
是搜索功能
有什么想法可以让函数执行而不阻塞机器人吗? (一段时间后,机器人在执行过程中离线。)
更新:
这是 self.searchTask
函数的代码片段:
async def searchTask(self, ctx, *args):
found = False
name = args[0].lower().
surname = args[1].lower()
await ctx.send("Searching data...")
with open(f"{CURRENT_DIR}/out.txt", "w") as fwrite:
flist = os.listdir(f"{CURRENT_DIR}/datab")
for x in flist:
with open(f"{CURRENT_DIR}/datab/{x}", "rb") as f:
for line in f:
...
fwrite.close()
if found:
await ctx.send("Done! Here's the result:")
await ctx.send(file=discord.File(f"{CURRENT_DIR}/out.txt"))
else:
await ctx.send("Can't find data")
您不能在异步代码中使用阻塞函数。似乎 searchTask
正在阻塞,因此您的事件循环正在停止。 Asyncio 事件循环为线程池或进程池中的 运行 阻塞函数提供了一个简单的 API,以防止它们阻塞您的事件循环。
编辑:示例:运行线程中的文件操作
def search_files():
found = False
flist = os.listdir(f"{CURRENT_DIR}/datab")
for x in flist:
with open(f"{CURRENT_DIR}/datab/{x}", "rb") as f:
for line in f:
found = found or is_found(line) # check your condition in is_found
return found
async def searchTask(self, ctx, *args):
name = args[0].lower()
surname = args[1].lower()
await ctx.send("Searching data...")
loop = asyncio.get_running_loop()
with open(f"{CURRENT_DIR}/out.txt", "w") as fwrite:
found = await loop.run_in_executor(None, search_files)
# write something to fwrite
# also do this in executor if it's a lot
fwrite.close() # this is unnecessary if you as using 'with'
if found:
await ctx.send("Done! Here's the result:")
await ctx.send(file=discord.File(f"{CURRENT_DIR}/out.txt"))
else:
await ctx.send("Can't find data")
我试图使用在 discord 上键入的命令从四个文件(它们有 4GB 大)中搜索数据。 搜索功能的执行时间需要十分钟左右,遍历4个文件;当我尝试连续键入命令两次时,第二个命令在第一个命令执行后执行(大约 10 分钟后)。
def main(self):
@self.client.command()
async def fsearch(ctx, *args):
self.client.loop.create_task(self.searchTask(ctx, *args))
self.searchTask
是搜索功能
有什么想法可以让函数执行而不阻塞机器人吗? (一段时间后,机器人在执行过程中离线。)
更新:
这是 self.searchTask
函数的代码片段:
async def searchTask(self, ctx, *args):
found = False
name = args[0].lower().
surname = args[1].lower()
await ctx.send("Searching data...")
with open(f"{CURRENT_DIR}/out.txt", "w") as fwrite:
flist = os.listdir(f"{CURRENT_DIR}/datab")
for x in flist:
with open(f"{CURRENT_DIR}/datab/{x}", "rb") as f:
for line in f:
...
fwrite.close()
if found:
await ctx.send("Done! Here's the result:")
await ctx.send(file=discord.File(f"{CURRENT_DIR}/out.txt"))
else:
await ctx.send("Can't find data")
您不能在异步代码中使用阻塞函数。似乎 searchTask
正在阻塞,因此您的事件循环正在停止。 Asyncio 事件循环为线程池或进程池中的 运行 阻塞函数提供了一个简单的 API,以防止它们阻塞您的事件循环。
编辑:示例:运行线程中的文件操作
def search_files():
found = False
flist = os.listdir(f"{CURRENT_DIR}/datab")
for x in flist:
with open(f"{CURRENT_DIR}/datab/{x}", "rb") as f:
for line in f:
found = found or is_found(line) # check your condition in is_found
return found
async def searchTask(self, ctx, *args):
name = args[0].lower()
surname = args[1].lower()
await ctx.send("Searching data...")
loop = asyncio.get_running_loop()
with open(f"{CURRENT_DIR}/out.txt", "w") as fwrite:
found = await loop.run_in_executor(None, search_files)
# write something to fwrite
# also do this in executor if it's a lot
fwrite.close() # this is unnecessary if you as using 'with'
if found:
await ctx.send("Done! Here's the result:")
await ctx.send(file=discord.File(f"{CURRENT_DIR}/out.txt"))
else:
await ctx.send("Can't find data")