gpt4 book ai didi

c# - 尝试从分页网址中获取所有项目时结果不一致

转载 作者:行者123 更新时间:2023-12-05 03:21:32 25 4
gpt4 key购买 nike

我在获取当前托管在 hubspot 中的所有表单时遇到问题。

我尝试使用一个简单的 for 循环,一次发出一个请求,一次获取一个表单,这种方法有效,但速度非常慢。

然后我认为如果我为每个请求创建一个单独的任务,然后让任务创建每个请求,并将它们存储在一个公共(public)列表中,可能会更好。

问题是我希望列表有 2000 个项目,但我似乎从来没有得到,我得到的项目数量似乎很不一致?

但是怎么会呢?

这就是我设置抓取方案的方式。

private static async Task<IEnumerable<HubspotModel>> GetForms(
string hubspotPath, int pageSize)
{
int totalResults;
int offset = 0;
List<HubspotModel> output = new();
List<Task> tasks = new();
using var client = new HttpClient();
{
System.Net.Http.Headers.HttpResponseHeaders requestHeader = client
.GetAsync($"https://api.hubapi.com{hubspotPath}?" +
$"hapikey={HubspotConfiguration.ApiKey}&limit={1}&offset={0}")
.Result.Headers;
totalResults = int.Parse(requestHeader.GetValues("x-total-count").First());
do
{
tasks.Add(Task.Run(() =>
{
int scopedOffset = offset;
IEnumerable<HubspotModel> forms = GetFormsFromHubspot(hubspotPath,
pageSize, offset, client);
output.AddRange(forms);

}).ContinueWith(requestReponse =>
{
if (requestReponse.IsFaulted)
{
Console.WriteLine("it failed");
}
}));
offset += pageSize;
}
while (totalResults > offset);

await Task.WhenAll(tasks);
}

return output;
}

private static IEnumerable<HubspotModel> GetFormsFromHubspot(string hubspotPath,
int pageSize, int offset, HttpClient client)
{
HttpResponseMessage request = client
.GetAsync($"https://api.hubapi.com{hubspotPath}?" +
$"hapikey={HubspotConfiguration.ApiKey}&limit={pageSize}&offset={offset}")
.Result;
request.EnsureSuccessStatusCode();
string content = request.Content.ReadAsStringAsync().Result;
IEnumerable<Dictionary<string, object>> jsonResponse = JsonSerializer
.Deserialize<IEnumerable<Dictionary<string, object>>>(content,
new JsonSerializerOptions() { });
var guid = Guid.Parse(jsonResponse.First()["guid"].ToString());
var forms = jsonResponse.Select(x => new HubspotModel()
{
id = Guid.Parse(x["guid"].ToString()),
FormName = x["name"].ToString(),
Form = x
});
return forms;
}

最佳答案

首先,我建议将 GetFormsFromHotspot 也设为 async 并使用 await client.GetAsync( ...)await request.Content.ReadAsStringAsync() 分别代替 client.GetAsync(...).ResultReadAsStringAsync().Result,因为使用 .Result 会阻塞当前线程,因此您将失去异步任务的优势。

但问题的主要原因应该是以下几点

GetFormsFromHubspot(hubspotPath, pageSize, offset, client);

在这里,您使用来自外部作用域的 offset 参数调用 GetFormsFromHubspot(并且该值不断变化),因此它不会使用您使用时的值创建了那个任务,但是当代码的特定部分真正被执行时,它使用它实际拥有的值。所以用作偏移量的值是非常随机的。您已经尝试创建一个

int scopedOffset = offset;

但你不使用它。而且你在错误的位置创建它。创建 scopedOffset 在任务的外部,但在循环体的内部。因此它将在任务创建时创建。因为它在循环体内,所以将为每个任务创建一个新值。

以下应该可以解决问题(在将 GetFormsFromHubspot 重构为异步之后。

do {
int scopedOffset = offset
tasks.Add(Task.Run(async () => {
IEnumerable<HubspotModel> forms = await GetFormsFromHubspot(hubspotPath, pageSize, scopedOffset, client);
output.AddRange(forms);
})
.ContinueWith(...);
);
offset += pageSize;
} while (totalResults > offset);

关于c# - 尝试从分页网址中获取所有项目时结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72949740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com