调用IHost.StopAsync时,IHostedServices的StopAsync为何被执行两次?
Discord.Addons.Hosting调用StopAsync导致IHostedServices停止两次的问题
使用Discord.Net结合Discord.Addons.Hosting开发Discord机器人时,调用IHost.StopAsync()后,所有IHostedService的StopAsync方法会被执行两次,日志中重复出现停止相关记录。
相关代码示例
自定义HostedService的StopAsync实现:
public override Task StopAsync(CancellationToken stoppingToken) { Logger.LogInformation("客户端 [{clientId}] 已停止。", Client.CurrentUser.Id); return base.StopAsync(stoppingToken); }
关闭机器人的命令代码:
[Command("shutdown")] [RequireUserPermission(GuildPermission.Administrator, Group = "Permission")] [RequireOwner(Group = "Permission")] public async Task Stop() { await _host.StopAsync(); }
关闭时的日志输出
[11:08:41 INF] 应用正在关闭... [11:08:46 INF] 客户端 [1007213990742610001] 已停止。 [11:08:46 INF] 客户端 [1007213990742610001] 已停止。 [11:08:46 INF] Discord.NET 托管服务正在停止 [11:08:46 INF] Discord.NET 托管服务正在停止 [11:08:46 INF] 网关:正在断开连接
解决办法
- 改用IHostApplicationLifetime触发关闭
Discord.Addons.Hosting内部已封装服务停止逻辑,直接调用IHost.StopAsync()会触发重复停止流程。建议通过IHostApplicationLifetime发送关闭信号:
private readonly IHostApplicationLifetime _appLifetime; // 构造函数注入IHostApplicationLifetime public YourCommandModule(IHostApplicationLifetime appLifetime) { _appLifetime = appLifetime; } [Command("shutdown")] [RequireUserPermission(GuildPermission.Administrator, Group = "Permission")] [RequireOwner(Group = "Permission")] public async Task Stop() { _appLifetime.StopApplication(); await Task.Delay(1000); // 可选:等待关闭流程执行完成 }
检查服务注册是否重复
确认你的自定义IHostedService没有被重复注册(比如同时使用AddHostedService<T>和Discord.Addons.Hosting的扩展方法注册),重复注册会导致每个实例都执行一次StopAsync。升级Discord.Addons.Hosting版本
部分旧版本的Discord.Addons.Hosting存在重复停止的bug,升级到最新稳定版本可能直接解决问题。
内容的提问来源于stack exchange,提问作者Darkhalo45
相关产品推荐
相关产品推荐

