单线程工作和多线程不工作
Single thread working and multithread not working
下面是我当前的代码,每次调用从 documentDB 中获取 500 个文档(JSON 格式)。我每次搜索只能做 500 次并将其添加到并发包中(并行)。获取的数据基于我提供给 API 的 ID 号,并从该范围中选择它。例如。 id = 500 [从 501 - 1000 获取文档]。下面的代码按预期用 25k 文档填充并发包。
int threadNumber = 5;
var concurrentBag = new ConcurrentBag<docClass>();
if (batch == 25000)
{
id = 500;
while (id <= 25000)
{
docs = await client.SearchDocuments<docClass>(GetFollowUpRequest(id), requestOptions);
docClass lastdoc = docs.Documents.Last();
lastid = lastdoc.Id.Id;
Parallel.ForEach(docs.Documents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, item =>
{
concurrentBag.Add(item);
});
id = id + 500;
}
}
我想在线程中 运行 整个 while 循环,这样我就可以多次调用 API 并并行获取 500 个文档。我尝试如下修改代码,但在整个 运行 之后,我总是看到并发包 'concurrentBag' 中仍然只有 500 个文档,并且跳过 id 保持在 500 并且不增加。
int threadNumber = 5;
var concurrentBag = new ConcurrentBag<docClass>();
if (batch == 25000)
{
id = 500;
Task[] tasks = new Task[threadNumber];
for (int j = 0; j < threadNumber; j++)
{
tasks[j] = Task.Run(async() =>
{
while (id <= 25000)
{
docs = await client.SearchDocuments<docClass>(GetFollowUpRequest(id), requestOptions);
docClass lastdoc = docs.Documents.Last();
lastid = lastdoc.Id.Id;
Parallel.ForEach(docs.Documents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, item =>
{
concurrentBag.Add(item);
});
id = id + 500;
}
});
}
}
你能帮我看看我做错了什么吗?
要从外部资源加载文档,请使用无需额外线程的异步方法。
请注意,当您并行下载外部资源时,额外的线程不起作用,只是在等待响应,所以线程只是被浪费了;)
异步方法提供了几乎同时启动多个请求的可能性,无需等待每个任务完成,而是仅在所有任务就绪时等待。
var maxDocuments = 25000;
var step = 500;
var documentTasks = Enumerable.Range(1, int.Max)
.Select(offset => step * offset)
.TakeWhile(id => id <= maxDocuments)
.Select(id => client.Search<docClass>(GetFollowUpRequest(id), requestOptions))
.ToArray();
await Task.WhenAll(documentTasks);
var allDocuments = documentTasks
.Select(task = task.Result)
.SelectMany(documents => documents)
.ToArray();
下面是我当前的代码,每次调用从 documentDB 中获取 500 个文档(JSON 格式)。我每次搜索只能做 500 次并将其添加到并发包中(并行)。获取的数据基于我提供给 API 的 ID 号,并从该范围中选择它。例如。 id = 500 [从 501 - 1000 获取文档]。下面的代码按预期用 25k 文档填充并发包。
int threadNumber = 5;
var concurrentBag = new ConcurrentBag<docClass>();
if (batch == 25000)
{
id = 500;
while (id <= 25000)
{
docs = await client.SearchDocuments<docClass>(GetFollowUpRequest(id), requestOptions);
docClass lastdoc = docs.Documents.Last();
lastid = lastdoc.Id.Id;
Parallel.ForEach(docs.Documents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, item =>
{
concurrentBag.Add(item);
});
id = id + 500;
}
}
我想在线程中 运行 整个 while 循环,这样我就可以多次调用 API 并并行获取 500 个文档。我尝试如下修改代码,但在整个 运行 之后,我总是看到并发包 'concurrentBag' 中仍然只有 500 个文档,并且跳过 id 保持在 500 并且不增加。
int threadNumber = 5;
var concurrentBag = new ConcurrentBag<docClass>();
if (batch == 25000)
{
id = 500;
Task[] tasks = new Task[threadNumber];
for (int j = 0; j < threadNumber; j++)
{
tasks[j] = Task.Run(async() =>
{
while (id <= 25000)
{
docs = await client.SearchDocuments<docClass>(GetFollowUpRequest(id), requestOptions);
docClass lastdoc = docs.Documents.Last();
lastid = lastdoc.Id.Id;
Parallel.ForEach(docs.Documents, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, item =>
{
concurrentBag.Add(item);
});
id = id + 500;
}
});
}
}
你能帮我看看我做错了什么吗?
要从外部资源加载文档,请使用无需额外线程的异步方法。
请注意,当您并行下载外部资源时,额外的线程不起作用,只是在等待响应,所以线程只是被浪费了;)
异步方法提供了几乎同时启动多个请求的可能性,无需等待每个任务完成,而是仅在所有任务就绪时等待。
var maxDocuments = 25000;
var step = 500;
var documentTasks = Enumerable.Range(1, int.Max)
.Select(offset => step * offset)
.TakeWhile(id => id <= maxDocuments)
.Select(id => client.Search<docClass>(GetFollowUpRequest(id), requestOptions))
.ToArray();
await Task.WhenAll(documentTasks);
var allDocuments = documentTasks
.Select(task = task.Result)
.SelectMany(documents => documents)
.ToArray();