C#递归调用API分页时如何避免StackoverflowException?
解决递归调用API导致的StackOverflowException问题
兄弟,这问题我太熟了!你现在碰到的是递归深度超限导致的栈溢出——每次同步递归调用都会在程序的调用栈里保存当前方法的上下文数据,350次调用直接把默认的栈空间撑爆了,自然就触发StackOverflowException了。
问题根源
你的GetData方法是同步递归实现:每次拿到nextpageToken就直接调用自身,每一层调用都会在栈上新增一个方法帧。而.NET的默认调用栈容量有限(通常只有几MB),当递归次数达到几百次时,栈空间就不够用了。
最优解决方案:改成迭代方式
把递归逻辑换成循环迭代,这样整个过程只会复用同一个方法栈帧,不管需要调用多少次API,都不会出现栈溢出的问题。下面是调整后的代码示例:
public static void GetData(Channel info) { string currentPageToken = null; // 循环获取数据,直到没有下一页token do { // 1. 调用API获取当前页数据和下一页token var apiResponse = FetchPageData(info, currentPageToken); // 2. 将数据存入数据库 SaveToDatabase(apiResponse.DataItems); // 3. 更新token为下一页的标识 currentPageToken = apiResponse.NextPageToken; } while (!string.IsNullOrEmpty(currentPageToken)); } // 抽离API调用逻辑,让主方法更清晰 private static ApiResponse FetchPageData(Channel info, string pageToken) { // 这里替换成你实际的API调用代码 using var httpClient = new HttpClient(); var requestUrl = $"https://your-api-endpoint.com/data?channelId={info.Id}"; if (!string.IsNullOrEmpty(pageToken)) { requestUrl += $"&pageToken={pageToken}"; } // 同步调用API(如果是异步场景可以改成async/await) var response = httpClient.GetFromJsonAsync<ApiResponse>(requestUrl).Result; return response; } // 假设的API响应模型,根据你的实际接口调整 public class ApiResponse { public List<YourDataModel> DataItems { get; set; } public string NextPageToken { get; set; } }
为什么这个方案可行?
迭代逻辑只会在一个方法栈帧里反复执行,每次循环都只是更新currentPageToken变量,不会不断创建新的栈帧。不管需要拉取10页还是1000页数据,都不会消耗额外的栈空间,彻底避免栈溢出问题。
额外提示:异步场景的处理
如果你的API调用是异步的(推荐用async/await),迭代方式同样适用,只需要把方法改成异步即可:
public static async Task GetDataAsync(Channel info) { string currentPageToken = null; do { var apiResponse = await FetchPageDataAsync(info, currentPageToken); await SaveToDatabaseAsync(apiResponse.DataItems); currentPageToken = apiResponse.NextPageToken; } while (!string.IsNullOrEmpty(currentPageToken)); } private static async Task<ApiResponse> FetchPageDataAsync(Channel info, string pageToken) { using var httpClient = new HttpClient(); var requestUrl = $"https://your-api-endpoint.com/data?channelId={info.Id}"; if (!string.IsNullOrEmpty(pageToken)) { requestUrl += $"&pageToken={pageToken}"; } return await httpClient.GetFromJsonAsync<ApiResponse>(requestUrl); }
内容的提问来源于stack exchange,提问作者Anirudha Gupta
相关产品推荐
相关产品推荐

