Python开发Discord Bot调用client.close()出现阻塞问题求助
解决Discord Bot中
client.close()阻塞的问题 问题分析
你的代码里await client.close()出现阻塞,核心原因是在协程中直接调用exit()会破坏异步事件循环的正常关闭流程,同时可能存在未完成的后台任务阻碍client.close()完成收尾工作。
修复方案
修改shutdown函数,移除exit()调用,改用异步事件循环的正常停止方式,并提前取消所有未完成的后台任务:
import asyncio async def shutdown(do_exit = True): # 执行自定义清理操作 talkbot_exit() print("talkbot closed") # 取消所有未完成的后台任务(避免阻塞关闭流程) for task in asyncio.all_tasks(): if task is not asyncio.current_task(): task.cancel() try: await task # 等待任务响应取消 except asyncio.CancelledError: pass # 关闭Discord客户端连接 await client.close() print("client closed") if do_exit is True: print("exiting...") # 停止事件循环,让程序自然退出 loop = asyncio.get_event_loop() loop.stop()
关键说明
- 避免直接调用
exit():exit()是同步终止进程的函数,在异步协程中调用会打断client.close()的异步收尾操作,导致资源无法正常释放,进而引发阻塞。 - 取消后台任务:如果你的Bot有后台运行的异步任务(比如定时任务、监听任务),这些未完成的任务会阻止
client.close()完成,因此需要提前取消并等待它们处理完取消信号。 - 事件循环正常停止:通过
loop.stop()让事件循环自然结束,配合client.run(TOKEN)的阻塞逻辑,程序会在事件循环停止后正常退出,无需强制终止。
额外检查点
- 确认
talkbot_exit()中没有同步阻塞的长时间操作,也没有未释放的资源(如文件句柄、数据库连接),这些也可能导致client.close()无法顺利完成。 - 确保调用
shutdown时是通过await shutdown()的方式,而非同步调用。
内容的提问来源于stack exchange,提问作者AGL
相关产品推荐
相关产品推荐

