首页 > 解决方案 > 在 HTTP 响应到达时解析它

问题描述

我的 Web API AAA调用另一个 API BBB来检索一个大型 JSON 数组(约 500-1000 KB,每个对象为 10 KB),它需要解析 JSON 数组以对其应用逻辑并将响应转发到API CCC

为了优化,我希望我的 Web API AAA 没有存储包含大型 JSON 数组的 HTTP 响应,因此不必将数组存储在 LOH(大型对象堆)中。

我认为解决这个问题的一个好主意是:不是等待完整的 JSON 数组被下载,而是可以在响应到达时解析响应的元素,以便我可以解析它,对其应用逻辑并转发我的 API CCC的内容?

所以我的 Web API 永远不会将大型 JSON 数组存储在内存中。通过在每个对象到达时对其进行解析,该对象非常小,以至于它将存储在 GEN 0 中,并被 GC 快速收集。

到目前为止我尝试了什么:

我的 API BBB 看起来像这样(简化):

[HttpGet("{id}")]
public IActionResult Get(int id)
{
    var text = System.IO.File.ReadAllText("C:\\Users\\John\\generated1000objects.json");
    var deserialized = JsonConvert.DeserializeObject<object[]>(text);
    return Ok(deserialized);
}

我要查询的代码

var httpClient = new HttpClient();

using (var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44328/api/values/4"))
using (var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
using (Stream stream = await response.Content.ReadAsStreamAsync())
using (StreamReader sr = new StreamReader(stream))
using (JsonReader reader = new JsonTextReader(sr))
{
    reader.SupportMultipleContent = true;
    while (true)
    {
         if (!reader.Read())
         {
                break;
         }

         JsonSerializer serializer = new JsonSerializer();
         var deserialize = serializer.Deserialize<object>(reader);

         Console.WriteLine(deserialize); // HERE it prints the whole JSON Array. I was expecting to deal with one object of the array
         Console.WriteLine("#################");

     }
}

我的限制:

我在 .NET Core 上使用 ASP.NET Core 2.2。

标签: c#asp.net-corememory-management

解决方案


查看您的解决方案,除非您期望它的大小大幅增长,否则我相信您可能会尝试进行微优化,这实际上会使您的过程比简单地以常规方式处理更脆弱。

您提到记录大小为 10k,响应大小为 500-1000k。这意味着总共有 50-100 条记录。

我相信您在尝试以块的形式解析响应时会遇到比在大对象堆上拥有对象所带来的任何影响更大的困难。从我在各种文档中可以找到的内容来看,使用内置库解析 JSON 文档的唯一方法是解析整个文档。任何分块都需要由您自己管理。


推荐阅读