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

当特定动作触发时,如何自动关闭NSwagStudio生成的全部客户端未完成HTTP请求?

实现NSwag生成客户端的批量请求取消方案

核心思路是通过共享取消令牌统一管控所有客户端的请求生命周期,触发动作时通过令牌取消所有未完成请求,具体实现步骤如下:

1. 创建全局取消令牌管理类

实现一个单例类来管理全局的CancellationTokenSource,负责触发取消和重置令牌:

public class RequestCancellationManager
{
    private CancellationTokenSource _requestCts = new CancellationTokenSource();

    // 提供给所有客户端请求使用的取消令牌
    public CancellationToken GlobalCancelToken => _requestCts.Token;

    // 触发批量取消动作
    public void CancelAllPendingRequests()
    {
        _requestCts.Cancel();
        // 取消后重置令牌源,避免后续新请求直接被取消
        _requestCts.Dispose();
        _requestCts = new CancellationTokenSource();
    }
}

2. 配置NSwag生成带取消令牌的客户端

在NSwagStudio中生成客户端时,开启取消令牌参数支持:

  • 进入「Client Settings」→「Cancellation」
  • 勾选「Generate cancellation token parameters」
  • 重新生成所有控制器客户端,此时每个请求方法都会自动带上CancellationToken参数(默认值为default)

生成后的客户端方法示例:

public async Task<UserDto> GetUserByIdAsync(int id, CancellationToken cancellationToken = default)
{
    // 内部请求逻辑会自动使用传入的取消令牌
}

3. 注入并关联全局令牌到所有客户端

在项目的依赖注入容器中注册RequestCancellationManager为单例,然后在使用客户端时,统一传入全局取消令牌:

注册单例(以ASP.NET Core为例)

// Program.cs
builder.Services.AddSingleton<RequestCancellationManager>();
// 注册所有NSwag生成的客户端(根据实际生成的类型调整)
builder.Services.AddHttpClient<IFirstControllerClient, FirstControllerClient>();
builder.Services.AddHttpClient<ISecondControllerClient, SecondControllerClient>();
// ... 其余8个客户端注册

使用客户端时传入全局令牌

public class BusinessService
{
    private readonly RequestCancellationManager _cancellationManager;
    private readonly IFirstControllerClient _firstClient;
    private readonly ISecondControllerClient _secondClient;
    // ... 注入其余8个客户端

    public BusinessService(RequestCancellationManager cancellationManager, 
                          IFirstControllerClient firstClient,
                          ISecondControllerClient secondClient,
                          // ... 其余客户端构造参数)
    {
        _cancellationManager = cancellationManager;
        _firstClient = firstClient;
        _secondClient = secondClient;
        // ... 初始化其余客户端
    }

    // 示例:发起多个客户端请求,全部关联全局取消令牌
    public async Task BatchRequest()
    {
        var token = _cancellationManager.GlobalCancelToken;
        var task1 = _firstClient.GetUserByIdAsync(1, token);
        var task2 = _secondClient.GetOrderListAsync(2024, token);
        // ... 其余客户端请求任务
        await Task.WhenAll(task1, task2);
    }
}

4. 触发批量取消动作

在需要取消所有请求的地方(比如API接口、前端按钮触发的后端逻辑),调用CancelAllPendingRequests方法:

[ApiController]
[Route("api/requests")]
public class RequestController : ControllerBase
{
    private readonly RequestCancellationManager _cancellationManager;

    public RequestController(RequestCancellationManager cancellationManager)
    {
        _cancellationManager = cancellationManager;
    }

    [HttpPost("cancel-all")]
    public IActionResult CancelAllRequests()
    {
        _cancellationManager.CancelAllPendingRequests();
        return Ok("所有未完成HTTP请求已取消");
    }
}

关键注意事项

  • 取消令牌是协作式的:HttpClient会在请求过程中主动检查令牌状态,请求会被优雅终止,而非强制中断
  • 每次取消后必须重置令牌源:已取消的令牌无法复用,重置后才能支持后续新发起的请求
  • 若未开启NSwag的取消令牌参数,可手动修改生成的客户端代码,为每个请求方法添加CancellationToken参数并传入请求逻辑中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:31:23