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

ASP.NET中GetStringAsync偶现返回Null及流式读取咨询

问题:流式航班数据获取时API响应超时返回Null,Postman测试正常

我尝试从流式数据源获取航班数据,该数据最终文件大小约10MB+,有时获取耗时超1分钟。以下控制器代码可正常运行,但当API响应耗时较长时返回结果为Null,而Postman测试相同请求未出现此问题。请问我的代码是否存在问题?是否支持流式读取逐步获取数据?

private async Task<List<Model>> GetFlightData() 
{ 
    using (var client = new HttpClient()) 
    { 
        var content = await client.GetStringAsync("http://api.travelpayouts.com/v1/flight_search_results?uuid=" + flightSearchID); 
        var result = JsonConvert.DeserializeObject<List<Model>>(content); 
        return result; 
    } 
}

分析与解决方案

1. 当前代码的核心问题

你的代码确实存在两个关键问题,导致长耗时请求返回Null:

  • 一次性加载全量数据:GetStringAsync会把整个10MB+的响应内容直接加载到内存里,不仅占用内存,一旦请求超时就会触发未捕获的异常,最终导致方法返回Null。
  • 超时设置不匹配:HttpClient默认超时是100秒,你的请求有时超过1分钟(60秒),接近甚至超过这个阈值就容易被取消;而Postman默认超时通常是5分钟,所以不会触发这个问题。

2. 实现流式读取的优化方案

想要支持流式读取、避免超时问题,我们可以调整代码逻辑,分步骤处理响应:

方案一:基础优化(调整超时+流式反序列化)

这个方案既解决超时问题,又不用一次性加载全量数据到内存:

private async Task<List<Model>> GetFlightData() 
{ 
    using (var client = new HttpClient()) 
    { 
        // 把超时时间调到5分钟,根据你的实际需求调整
        client.Timeout = TimeSpan.FromMinutes(5);
        
        // 使用ResponseHeadersRead选项,拿到响应头就开始读内容,不用等全量下载完
        using (var response = await client.GetAsync(
            $"http://api.travelpayouts.com/v1/flight_search_results?uuid={flightSearchID}", 
            HttpCompletionOption.ResponseHeadersRead))
        {
            // 先确保API返回成功,避免无效响应
            response.EnsureSuccessStatusCode();
            
            // 流式读取内容并逐步反序列化
            using (var stream = await response.Content.ReadAsStreamAsync())
            using (var reader = new StreamReader(stream))
            using (var jsonReader = new JsonTextReader(reader))
            {
                var serializer = new JsonSerializer();
                return serializer.Deserialize<List<Model>>(jsonReader);
            }
        }
    } 
}

方案二:添加异常捕获(方便排查问题)

加上异常捕获,能明确知道请求失败的原因,避免莫名其妙返回Null:

private async Task<List<Model>> GetFlightData() 
{ 
    try
    {
        using (var client = new HttpClient()) 
        { 
            client.Timeout = TimeSpan.FromMinutes(5);
            
            using (var response = await client.GetAsync(
                $"http://api.travelpayouts.com/v1/flight_search_results?uuid={flightSearchID}", 
                HttpCompletionOption.ResponseHeadersRead))
            {
                response.EnsureSuccessStatusCode();
                
                using (var stream = await response.Content.ReadAsStreamAsync())
                using (var reader = new StreamReader(stream))
                using (var jsonReader = new JsonTextReader(reader))
                {
                    var serializer = new JsonSerializer();
                    return serializer.Deserialize<List<Model>>(jsonReader);
                }
            }
        } 
    }
    catch (Exception ex)
    {
        // 这里可以换成你的日志组件,记录异常详情
        Console.WriteLine($"获取航班数据出错:{ex.Message}\n{ex.StackTrace}");
        // 根据业务需求返回空列表或者null,建议返回空列表更安全
        return new List<Model>();
    }
}

3. 额外建议

  • 复用HttpClient实例:每次创建新的HttpClient会消耗Socket资源,建议用单例或者依赖注入的方式复用一个实例。
  • 检查API限流:如果频繁超时,也可能是API对请求频率有限制,可以查看API文档确认。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:57:49