首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从C#中偏移量为100的API中获取所有记录

从C#中偏移量为100的API中获取所有记录
EN

Stack Overflow用户
提问于 2022-11-29 02:57:53
回答 1查看 62关注 0票数 1

我正在使用C#和ASP.NET Core6MVC。

我需要使用偏移量从API中获取所有结果,无论是64条记录还是6300条记录。调整偏移量,执行并发调用或并行调用,以一次获得所有记录。我需要用最好的方法。

我正在调用一个API,它会在每次调用中产生100条最大记录。虽然总的结果(totalResult)可以是65,120,1500或2520,或6534等。有一个偏移整数,我可以传递到API,以得到进一步的100个结果每次。默认情况下,它是零,这可以带来100个最大记录。

例如,对于65的totalResult,偏移量0就足够了,因为它将带来所有65条记录。对于150的totalResult,偏移量0将带来100条记录,然后在下一次迭代中,偏移量必须为100才能带来更多记录。同样地,对于6530最大记录,偏移必须调整100,200,300.得到所有的结果。

现在,我需要并行运行这个任务,以避免延迟时间。

这是我的职责:

代码语言:javascript
复制
var offset = 0

// My async call method
var addressResult = await _postcode.GetAddresses(strPostcode, offset);

if (addressResult?.Results != null && addressResult.Results.Any())
{
        // concurrency code to run here with offset
        int total = addressResult.Header.TotalResults; //Total Result e,g 6500
        var thePostcoderesult = addressResult.Results;

        // max result could be any number depends on the Total Result if it is 
        int maxresult =  thePostcoderesult.Count(); 
}

因此,当对API的所有并发调用结束时,thePostcoderesult应该将所有结果都添加到其中。

代码语言:javascript
复制
var thePostcoderesult = addressResult.Results;

现在,我知道我们可以通过

代码语言:javascript
复制
await Parallel.ForEachAsync(offsets, options, async (offset, ct) =>

在帖子的帮助下,勾选答案How to make multiple API calls faster?

我试着实现这个逻辑--但它只给了我1000个结果,因为它与偏移量有关,并行循环不对齐。因为任务只运行了10次,结果只有1000个--尽管我正在搜索的邮政编码是1630。

这里是我更新的代码,但正如我提到的,它不会等待完成或运行,直到偏移的总数。

代码语言:javascript
复制
var offset = 0
var addressResult = await _postcode.GetAddresses(strPostcode, offset);

if (addressResult?.Results != null && addressResult.Results.Any())
{
    int total = addressResult.Header.TotalResults;

    // Setting offset here - but something is not right
    IEnumerable<int> offsets = Enumerable
            .Range(0, total)
            .Select(n => checked(n * 100))
            .TakeWhile(offset => offset < Volatile.Read(ref total));

    // wanted to use 10 parallel threads which is a safe bet I believe
    var options = new ParallelOptions() { MaxDegreeOfParallelism = 10 };
 
    var thePostcoderesult = new List<AddressResult>();
    await Parallel.ForEachAsync(offsets, options, async (offset, ct) =>
        {
            var addressResult = await _postcode.GetAddresses(strPostcode, offset);

            if (offset == 0)
            {   //I am not using it
                //Volatile.Write(ref total, Jresult.Results.Count());
            }
            thePostcoderesult.AddRange(addressResult.Results);
        });

    return thePostcoderesult;
}

为详细的帖子事先表示歉意-如果您能帮助做这个更正确或整洁的方式,欢迎您。

非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-29 03:59:29

你有很多事情要做,我觉得没必要那么复杂。由于最初的GetAddresses调用似乎告诉您将拥有多少记录,所以您可以这样做:

代码语言:javascript
复制
var initialResponse = await _postcode.GetAddresses(strPostcode, 0);

if (initialResponse?.Results == null || !initialResponse.Results.Any())
{
  return;
}

var totalPostCodeResults = new AddressResult[initialResponse.Header.TotalResults];

// fill up to the first 100 since you have it and bail if that's all there is
FillItems(initialResponse.Results, totalPostCodeResults, 0);

if(totalPostCodeResults.Length <= 100)
  return totalPostCodeResults;

// Fill the offsets (aka start indexes) starting at 100
var offsets = new List<int>();
var offset = 100;
while(offset < totalPostCodeResults.Length)
{
  offsets.Add(offset);
  offset+=100;
}

// TODO: add the last one using modulus

// Kick off a task for each offset range
var tasks = new Task[offsets.Count()];
for(int i = 0; i < tasks.Length; i++)
{
  // copy i to scoped variable to avoid parallel messiness
  var index = i;
  tasks[index] = Task.Run(async () => {
    var response = await _postcode.GetAddresses(strPostcode, offsets[index]);
    FillItems(response.Results, totalPostCodeResults, offsets[index]);
  }
}

// Wait for all of them to finish
Task.WaitAll(tasks);

return totalPostCodeResults

void FillItems(List<AddressResult> results, AddressResult[] totalArray, int startIndex)
{
  var index = startIndex;
  results.ForEach(item => totalArray[index++] = item);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74608696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档