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

ASP.NET Core 6 MVC并行分页获取API全量数据问题求助

正确实现并行获取全量分页API数据方案

首先明确核心逻辑:先通过首次请求拿到总数据量totalResult,计算出所有需要的偏移量(offset),再并行请求每个偏移量对应的分页数据,最后合并结果。你之前的问题大概率是偏移量列表生成不全或者并行写入时的线程安全问题导致数据丢失,以下是完整的修正实现:

核心实现代码

using System.Collections.Concurrent;
using System.Net.Http.Json;

public class DataFetchService
{
    private readonly HttpClient _httpClient;
    // 控制并行度,避免触发API限流,可根据实际API要求调整
    private readonly int _maxDegreeOfParallelism = 5;

    public DataFetchService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<List<TData>> FetchAllDataAsync<TData>(string apiUrl)
    {
        // 1. 首次请求获取总数据量与第一页数据
        var firstPageResponse = await _httpClient.GetFromJsonAsync<ApiResponse<TData>>($"{apiUrl}?offset=0&limit=100");
        if (firstPageResponse == null || firstPageResponse.TotalResult == 0)
            return new List<TData>();

        var allData = new ConcurrentBag<TData>(firstPageResponse.Data);
        int total = firstPageResponse.TotalResult;
        // 计算总页数,向上取整避免遗漏最后一页
        int totalPages = (int)Math.Ceiling((double)total / 100);

        // 2. 生成剩余需要请求的偏移量列表(从第2页开始)
        var offsets = Enumerable.Range(1, totalPages - 1).Select(page => page * 100).ToList();

        // 3. 并行请求剩余分页数据
        var parallelOptions = new ParallelOptions
        {
            MaxDegreeOfParallelism = _maxDegreeOfParallelism
        };

        await Parallel.ForEachAsync(offsets, parallelOptions, async (offset, cancellationToken) =>
        {
            var response = await _httpClient.GetFromJsonAsync<ApiResponse<TData>>(
                $"{apiUrl}?offset={offset}&limit=100", cancellationToken);
            
            if (response?.Data != null)
            {
                foreach (var item in response.Data)
                {
                    allData.Add(item);
                }
            }
        });

        return allData.ToList();
    }
}

// 定义API响应模型,请根据实际API返回结构调整字段
public class ApiResponse<T>
{
    public int TotalResult { get; set; }
    public List<T> Data { get; set; } = new List<T>();
}

关键修正点说明

  • 准确计算偏移量:用Math.Ceiling((double)total / 100)计算总页数,确保不会遗漏最后一页(比如1630条数据会生成17个偏移量:0,100,...,1600)
  • 线程安全集合:使用ConcurrentBag<T>存储结果,避免并行写入时的线程冲突导致数据丢失
  • 并行度控制:通过ParallelOptions.MaxDegreeOfParallelism限制并发数,防止触发API的限流机制,同时平衡效率与稳定性
  • 取消令牌支持:在并行调用中传入cancellationToken,支持请求取消场景

常见问题排查

  1. API返回的TotalResult不准确:确认API返回的totalResult是真实总数据量,而非当前页的条目数
  2. 并行度设置过高:如果API有QPS限制,过高的并发会导致请求失败,可降低_maxDegreeOfParallelism的值
  3. 偏移量计算错误:避免直接用整数除法(比如total / 100会把1630算成16,漏掉最后30条),必须转成浮点数后取整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:01:26