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

.NET调用REST服务并发请求触发CancellationTokenSource已释放异常求解

问题原因

你遇到的异常核心是绑定请求的CancellationToken对应的CancellationTokenSource被提前释放,加上HttpClient的错误用法放大了并发场景下的问题:

  1. 本地环境网络延迟低、请求处理快,所有请求能在CancellationTokenSource释放前完成,所以不会报错;部署环境网络波动大、请求处理耗时更长,第二个请求还在执行时对应的CancellationTokenSource已经被释放,就触发了ObjectDisposedException。
  2. 你每次请求都新建HttpClient实例的写法是经典错误,该类设计为可复用实例,频繁创建会导致套接字资源耗尽、大量TIME_WAIT连接残留,高并发下会触发各类资源释放相关的异常。

解决方案

1. 修正CancellationTokenSource的生命周期

确保所有绑定了对应令牌的异步任务全部执行完成后,再释放CancellationTokenSource。最常见的错误写法是在using块内启动并发任务后,没有等待所有任务完成就退出了using作用域,导致CancellationTokenSource被提前释放:

// 错误示例
using var cts = new CancellationTokenSource();
// 直接弃元任务,没有等待执行完成
_ = CreateEmployeeRequestAsync(req1, cts.Token);
_ = CreateEmployeeRequestAsync(req2, cts.Token);
// 退出using作用域后cts直接被释放,后台还在运行的请求就会抛出异常

修正为等待所有并发任务完成再退出作用域:

// 正确示例
using var cts = new CancellationTokenSource();
var task1 = CreateEmployeeRequestAsync(req1, cts.Token);
var task2 = CreateEmployeeRequestAsync(req2, cts.Token);
// 等待所有任务执行完成后再释放cts
await Task.WhenAll(task1, task2);

2. 修复HttpClient的使用方式

禁止每次请求新建HttpClient实例,改为复用单例实例,或使用IHttpClientFactory创建实例:

// 静态单例复用示例(适用于非ASP.NET Core场景)
private static readonly HttpClient _sharedHttpClient = new HttpClient { BaseAddress = m_baseAddress };

// 静态构造函数初始化配置,只执行一次
static 你的类名()
{
    var headers = _sharedHttpClient.DefaultRequestHeaders;
    headers.Accept.Clear();
    headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MEDIA_TYPE_JSON));
    // 非必要不要开启ConnectionClose,复用连接性能更高
    // headers.ConnectionClose = true;
}

[NotNull]
private HttpClient GetHttpClient() 
{
    return _sharedHttpClient;
}

如果是ASP.NET Core项目,直接注入IHttpClientFactory调用CreateClient方法获取实例即可,框架会自动处理连接复用和资源释放逻辑。

3. 可选优化

移除PostAsync方法内每次新建Logger实例的逻辑,复用全局Logger实例,减少不必要的资源开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:18:04