【问题标题】:Use LINQ (Skip and Take) methods with HttpClient.GetAsync method for improving performance?使用带有 HttpClient.GetAsync 方法的 LINQ(Skip and Take)方法来提高性能?
【发布时间】:2018-10-09 03:16:01
【问题描述】:

我使用以下代码检索 JSON 提要的内容,如您所见,我使用了分页技术和 SkipTake 方法,如下所示:

[HttpGet("[action]")]
public async Task<myPaginatedReturnedData> MyMethod(int page)
{
    int perPage = 10;
    int start = (page - 1) * perPage;

    using (HttpClient client = new HttpClient())
    {
        client.BaseAddress = new Uri("externalAPI");
        MediaTypeWithQualityHeaderValue contentType =
            new MediaTypeWithQualityHeaderValue("application/json");
        client.DefaultRequestHeaders.Accept.Add(contentType);
        HttpResponseMessage response = await client.GetAsync(client.BaseAddress);
        string content = await response.Content.ReadAsStringAsync();
        IEnumerable<myReturnedData> data = 
               JsonConvert.DeserializeObject<IEnumerable<myReturnedData>>(content);
        myPaginatedReturnedData datasent = new myPaginatedReturnedData
        {
            Count = data.Count(),
            myReturnedData = data.Skip(start).Take(perPage).ToList(),
        };
        return datasent;
    }
}

我的分页工作正常,但是我看不到任何性能改进,我知道这是因为每次我请求一个新页面时,它都会一次又一次地调用 API 在检索所有内容后,它会使用过滤它SkipTake 方法,我正在寻找一种方法将SkipTake 方法与我的HttpClient 一起应用,以便它只检索每个页面所需的记录。可能吗?如果有,怎么做?

【问题讨论】:

  • 如果使用 httpClient 获取数据是耗时的操作 - 为什么不缓存数据并在后续请求中使用?
  • @RahulAgarwal 如果我从数据库中检索了我的数据,我可以使用SkipTake 方法,这样它只会给我需要的记录,但我正在寻找一种应用方式Skip 和 Take 方法与我的 HttpClient.GetAsync 方法一起使用,但我不能将这些方法与 HttpClient.GetAsync 一起使用。
  • 意思是提取这个操作IEnumerable&lt;myReturnedData&gt; data = JsonConvert.DeserializeObject&lt;IEnumerable&lt;myReturnedData&gt;&gt;(content); 来分离方法并使用缓存(比如InMemory Cache)仅在第一次获取数据。有了这个,你可以避免对服务器上的每个后续请求进行网络调用
  • @RahulAgarwal 所以你的意思是说无论如何都不能只从那个 API 请求和检索所需的记录?用于缓存它应该第一次检索所有记录,如果我想这样做,我更喜欢使用没有服务器端分页的 Angular 分页并使用内存中的完整集合。
  • 我认为在这种情况下服务器返回 json 数据应该尊重分页和跳过。

标签: c# angular linq async-await


【解决方案1】:

为了将 Take/Skip 应用于数据检索,服务器必须了解它们。您可以使用 IQueryable LINQ 提供程序来做到这一点(请参阅 [1] 以了解其复杂程度),或者更好的是,将适当的值传递给 client.GetAsync 调用,类似于

HttpResponseMessage response = await client.GetAsync(client.BaseAddress + $"?skip={start}&take={perPage}");

当然,您的服务器端代码必须正确解释那些skiptake 参数;这不是自动的

您可能还想查看 OData(请参阅 [2]),但我从未在生产中实际使用过它;我只知道它存在。

[1]https://msdn.microsoft.com/en-us/library/bb546158.aspx

[2]https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/calling-an-odata-service-from-a-net-client

【讨论】:

  • 没有。它仍然检索所有记录!
  • client.GetAsync(client.BaseAddress + $"?skip={start}&amp;take={perPage}") 服务器返回数据需要接受这个 OData 特定协议
  • @J.P -- 你需要编写代码来解释跳过/接受参数,或者使用 OData 来自动解释类似的东西。
  • 好的,但是我该怎么做呢?
猜你喜欢
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多