You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Discord Python Bot因长耗时await函数触发心跳阻塞警告?

解决Discord Python Bot心跳阻塞警告的方案

你的问题根源是check_all函数执行耗时过长,阻塞了Discord.py的事件循环。Discord Bot需要定期发送心跳包维持连接,一旦事件循环被卡住超过10秒,就会触发heartbeat blocked警告。

下面是具体的解决方案:

把耗时的check_all函数放到独立线程中执行,让事件循环能继续处理心跳和其他任务,同时在函数执行完成后自动获取结果并发送消息。

代码修改示例(Python 3.9+)

使用asyncio.to_thread直接将同步阻塞函数放到线程池执行:

import asyncio
from datetime import datetime
import discord
from discord.ext import tasks

@tasks.loop(minutes=5)
async def send_message():
    channel = discord.utils.get(client.get_all_channels(), name="bremen")
    current_time = datetime.now(BerlinTz)
    formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S')
    await channel.send(f'{formatted_time}: Checking all cities ...')
    
    # 将耗时函数放入线程执行,不阻塞事件循环
    response = await asyncio.to_thread(check_all)
    
    formatted_output = format_data(response)
    await channel.send(formatted_output)

兼容Python 3.8及以下版本的写法

用loop.run_in_executor手动提交任务到线程池:

import asyncio
from datetime import datetime
import discord
from discord.ext import tasks

@tasks.loop(minutes=5)
async def send_message():
    channel = discord.utils.get(client.get_all_channels(), name="bremen")
    current_time = datetime.now(BerlinTz)
    formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S')
    await channel.send(f'{formatted_time}: Checking all cities ...')
    
    # 获取事件循环,提交任务到默认线程池
    loop = asyncio.get_event_loop()
    response = await loop.run_in_executor(None, check_all)
    
    formatted_output = format_data(response)
    await channel.send(formatted_output)

关键说明

  • 之前用asyncio.create_task无效的原因:如果check_all是同步阻塞函数,create_task只是把它加入事件循环的任务队列,依然会占用事件循环资源导致阻塞。只有放到线程池,才能真正解放事件循环。
  • 确保check_all是线程安全的:如果函数内有共享资源操作(比如全局变量、数据库连接),需要添加线程锁避免冲突。
  • 该方案天然支持“执行完成后通知”:await会等待线程中的函数执行完毕,自动获取结果后继续执行消息发送逻辑,无需额外的通知机制。

内容的提问来源于stack exchange,提问作者Ilyas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:06:12