在http响应到达时解析

时间:2019-03-17 21:32:45

标签: c# asp.net-core memory-management

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

为了进行优化,我希望我的webapi AAA没有存储包含大型json数组的http响应,因此该数组不必存储在LOH(大对象堆)中。

我认为解决此问题的好主意是:与其等待完整的json数组下载,不如在响应到达时解析响应的元素,以便我可以解析,应用逻辑,并将内容转发到我的API CCC ?因此,我的webapi从未将大型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("#################");

     }
}

我的约束:

  • 我无法修改发送大型json数组的API BBB
  • 我的API CCC无法直接调用api BBB来检索大型json数组

我在带有ASP.NET CORE 2.2的.NET CORE上

1 个答案:

答案 0 :(得分:0)

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

您提到记录大小为10k,响应大小为500-1000k。总共转换为50-100条记录。

我相信,比起将对象放置在大对象堆上所带来的任何影响,尝试分块解析响应将遇到更多的困难。从各种文档中可以发现,使用内置库解析JSON文档的唯一方法是解析整个文档。任何分块都需要您自己管理。