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

使用HttpWebRequest调用Azure端点偶发连接失败,代码是否存在问题?

代码存在的核心问题

  • HttpWebResponse资源未释放导致连接池耗尽
    你代码中从GetRESTResponse返回的HttpWebResponse对象实现了IDisposable接口,但全程没有调用Dispose()或者用using包裹释放资源。.NET 中HttpWebRequest默认依赖系统连接池管理TCP连接,单域名默认最大连接数仅为2,当未释放的连接累计超过上限后,新的请求会在连接池排队等待空闲连接,排队超时就会抛出你遇到的连接失败错误,而且这种情况请求根本没有发出去,所以服务侧收不到请求记录,完全符合你描述的现象。
  • 请求流未做安全释放
    GetRESTResponse方法中写入请求体的Stream dataStream仅在正常执行时调用了Close(),如果写入过程中抛出异常,Close()逻辑不会执行,会额外占用资源。
  • 编码使用不规范
    序列化请求体时用了Encoding.Default,这个编码取决于运行程序的系统默认配置,发application/json格式请求应该统一用Encoding.UTF8,避免乱码导致的服务端解析失败。
  • 拼写错误
    catch (WebException e)块中打日志的e.Reponse拼写错误,正确为e.Response,会导致异常日志收集不全。

修复方案

  1. 所有用到HttpWebResponse的地方都用using包裹,确保资源释放,修改SingleRead方法:
public T SingleRead<T>(string url, string method, object entity = null)
{
    T returnValue = default(T);
    using (var resp = GetRESTResponse(url, method, entity))
    {
        string responseText = GetResponseText(resp);
        try
        {
            returnValue = JsonConvert.DeserializeObject<T>(responseText);
        }
        catch (Exception ex)
        {
            return default(T);
        }
    }
    return returnValue;
}
  1. 请求流用using包裹自动释放,不需要手动调用Flush和Close,修改GetRESTResponse里的请求体写入逻辑:
if (entity != null)
{
    byte[] byteArray = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(entity));
    req.ContentLength = byteArray.Length;
    req.ContentType = "application/json";

    using (Stream dataStream = req.GetRequestStream())
    {
        dataStream.Write(byteArray, 0, byteArray.Length);
    }
}
  1. 可以适当调高连接池上限,在程序启动时添加配置,数值根据实际并发请求量调整即可:
ServicePointManager.DefaultConnectionLimit = 512;
  1. 长期迭代建议替换为HttpClient静态单例实现,这是.NET官方现在推荐的HTTP请求实现,不需要手动管理连接释放,天然避免连接池耗尽问题,性能和稳定性都优于HttpWebRequest。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:36:03