当特定动作触发时,如何自动关闭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
相关产品推荐
相关产品推荐

