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

.NET 8 Discord Bot出现Delegate实例方法null 'this'错误求助

问题分析与解决方案

错误原因

你遇到的System.MulticastDelegate.ThrowNullThisInDelegateToInstance()异常,本质是委托绑定的目标实例为null导致的。具体触发点在这段代码:

if (!Array.Exists(allowedSites, context.Message.Content.Contains))

你直接把context.Message.Content.Contains作为委托传递给Array.Exists,但如果context.Message.Content是null(比如消息被编辑成空内容),这个委托绑定的目标对象(即string实例)就会是null,调用时就会抛出该异常。

修复步骤

1. 修复委托调用的空值问题

改用lambda表达式替代直接传递实例方法,同时先判断Content是否为null:

if (context.Message.Content == null || !Array.Exists(allowedSites, site => context.Message.Content.Contains(site)))

这样能避免Content为null时触发的委托实例错误。

2. 缓存允许站点列表,减少IO操作

当前代码每次调用CheckChannelAsync都读取一次文件,频繁IO可能加剧短时间内的错误频率。建议在服务初始化时加载一次并缓存:

private readonly string[] _allowedSites;

public MessageService(DiscordSocketClient client, ILogger<DiscordClientService> logger)
    : base(client, logger)
{
    client.MessageUpdated += OnMessageUpdated;
    // 初始化时加载一次,避免重复读文件
    _allowedSites = File.ReadAllLines(Utilities.GetLocalFilePath("AllowedSites.txt"));
}

后续在CheckChannelAsync中直接使用_allowedSites即可。

3. 优化异步处理逻辑

OnMessageUpdated里用Task.Run包裹异步逻辑没必要,还可能浪费线程池资源,改成标准异步方法:

private async Task OnMessageUpdated(Cacheable<IMessage, ulong> oldMessage, SocketMessage newMessage, ISocketMessageChannel channel)
{
    if (newMessage is not SocketUserMessage message) return;
    var context = new SocketCommandContext(Client, message);

    if (context.Channel.Id == _botOptions.ChannelId)
        await CheckChannelAsync(context);
}

4. 增加额外空值防护

虽然你确认context不为null,但可以给context.Message加空值判断,覆盖意外场景:

// 放在CheckChannelAsync方法开头
if (context.Message == null) return false;

总结

短时间内多次触发错误,大概率是因为有用户频繁将消息编辑为空内容,导致context.Message.Content为null触发异常。按照上述步骤修复后,即可解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:05:09