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

循环调用API时请求中断:连接意外关闭问题排查

循环调用API时首次请求成功,后续请求报错:连接意外关闭

我在通过for循环调用API时遇到问题:首次请求(i=1)执行成功,但后续请求均返回错误信息:{"the request was aborted: the connection was closed unexpectedly."}。

以下是我的代码:

for (var i = 1; i <= 4; i++)
{
    var token = GetToken();
    string token_cookie = ConfigurationManager.AppSettings["token_cookie"].ToString();
    var request = System.Net.WebRequest.Create(url + "/Revenue/GetList") as System.Net.HttpWebRequest;
    request.Method = "POST";
    request.UserAgent = "api-explorer-client";
    request.ContentType = "application/json";
    request.Headers["Cookie"] = token_cookie;
    request.Headers["Authorization"] = "Bearer " + token;

    string body = "{" + "\n " + "\"DateFrom\": \"" + "2024-09-01" + "\"," 
              + "\n " + "\"DateTo\": \"" + DateTime.Now.ToString("yyyy-MM-dd") + "\"," 
              + "\n " + "\"BranchID\": \"" + "0" + "\"," 
              + "\n " + "\"DataType\": \"" + "all" + "\"," 
              + "\n " + "\"PagingNumber\": \"" + 1.ToString() + "" + "\"" 
              + "\n " + "}";

    byte[] postBytes = Encoding.UTF8.GetBytes(body);
    //request.ContentLength = postBytes.Length;
    using (Stream stream = request.GetRequestStream())
    {
        stream.Write(postBytes, 0, postBytes.Length);//error here
    }
    string responseContent = "";
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
        {
            responseContent = streamReader.ReadToEnd();
            RevenueList revenueList = JsonConvert.DeserializeObject<RevenueList>(responseContent);
            DataTable RevList = new DataTable();
            RevList = ToDataTable<RevenueListData>(revenueList.Data);
                       
            InsertBulkTable(RevList, "RevenueList");
            //currentPage++;
            streamReader.Close();
        }
    }
    request.Abort();
}

我尝试了其他方法,但仍出现该错误。


问题原因及修复方案

1. 恢复ContentLength设置

你注释掉了request.ContentLength = postBytes.Length;,部分服务器要求明确的请求体长度才能正常处理请求,取消注释这行代码:

byte[] postBytes = Encoding.UTF8.GetBytes(body);
request.ContentLength = postBytes.Length; // 取消注释此行

2. 调整连接复用相关设置

HttpWebRequest默认复用连接,若服务器端未正确支持Keep-Alive或限制了连接数,会导致后续请求失败。在循环前添加以下配置:

ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 10; // 调高并发连接数限制
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // 指定TLS版本,避免协议兼容问题

3. 优化资源释放与异常捕获

当前代码缺少异常处理,一旦请求出错可能导致资源泄漏。添加try-catch-finally确保资源被正确清理:

for (var i = 1; i <= 4; i++)
{
    HttpWebRequest request = null;
    try
    {
        var token = GetToken();
        string token_cookie = ConfigurationManager.AppSettings["token_cookie"].ToString();
        request = System.Net.WebRequest.Create(url + "/Revenue/GetList") as System.Net.HttpWebRequest;
        // ... 其他request配置代码

        byte[] postBytes = Encoding.UTF8.GetBytes(body);
        request.ContentLength = postBytes.Length;
        using (Stream stream = request.GetRequestStream())
        {
            stream.Write(postBytes, 0, postBytes.Length);
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
            {
                responseContent = streamReader.ReadToEnd();
                // ... 反序列化与数据插入逻辑
            }
        }
    }
    catch (WebException ex)
    {
        // 打印错误详情便于排查
        Console.WriteLine($"第{i}次请求失败:{ex.Message}");
        if (ex.Response != null)
        {
            using (StreamReader sr = new StreamReader(ex.Response.GetResponseStream()))
            {
                Console.WriteLine("服务器返回错误内容:" + sr.ReadToEnd());
            }
        }
    }
    finally
    {
        request?.Abort();
    }
}

4. 改用HttpClient(推荐)

HttpWebRequest是旧版API,HttpClient是.NET官方推荐的HTTP客户端,自带连接池管理,稳定性更强:

// 全局初始化一次HttpClient,不要在循环内重复创建
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("api-explorer-client");
string token_cookie = ConfigurationManager.AppSettings["token_cookie"].ToString();
httpClient.DefaultRequestHeaders.Add("Cookie", token_cookie);
var token = GetToken(); // 若Token有效期覆盖所有请求,可移到循环外
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

for (var i = 1; i <= 4; i++)
{
    var requestBody = new 
    {
        DateFrom = "2024-09-01",
        DateTo = DateTime.Now.ToString("yyyy-MM-dd"),
        BranchID = "0",
        DataType = "all",
        PagingNumber = "1"
    };

    var jsonBody = JsonConvert.SerializeObject(requestBody);
    var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

    try
    {
        var response = await httpClient.PostAsync(url + "/Revenue/GetList", content);
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        // ... 反序列化与数据插入逻辑
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine($"第{i}次请求失败:{ex.Message}");
    }
}

内容的提问来源于stack exchange,提问作者Tân Nguyễn Đức

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:14:57