.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
相关产品推荐
相关产品推荐

