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

调用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] 网关:正在断开连接

解决办法

  1. 改用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); // 可选:等待关闭流程执行完成
}
  1. 检查服务注册是否重复
    确认你的自定义IHostedService没有被重复注册(比如同时使用AddHostedService<T>和Discord.Addons.Hosting的扩展方法注册),重复注册会导致每个实例都执行一次StopAsync。

  2. 升级Discord.Addons.Hosting版本
    部分旧版本的Discord.Addons.Hosting存在重复停止的bug,升级到最新稳定版本可能直接解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:54:21