单线程工作和多线程不工作

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();