0

Не могу понять, как получить много тасков в цикле для функции, чтобы потом вернуть Task.WhenAll. Надо что то использовать вместо Task.Run, т.к. он съедает N потоков.

  List<Task<Model>> models = new List<Task<Model>>();
        foreach (var item in items)
        {
            foreach (var communityId in item.CommunityIds)
            {
                models.Add(Task.Run(() =&gt; ToContentItem(item, addresses.TryGetValueOrDefault(item.Id), chats.TryGetValueOrDefault(item.Id), communities.TryGetValueOrDefault(communityId)))); 
            }
        }

        return await Task.WhenAll(models);

Чем можно заменить Task.Run?

Пытался сделать так:

      foreach (var communityId in item.CommunityIds)
                {
                    baseNewsContentItems.Add(new Task(() => {
                    ToContentItem(item, addresses.TryGetValueOrDefault(item.Id), chats.TryGetValueOrDefault(item.Id), communities.TryGetValueOrDefault(communityId))
                    });
                ) ; 
            }

но код ругается, что не хватает ")", хотя вроде все есть

Mihail
  • 45
  • 3
    он съедает N потоков - и что в этом плохого? Немного не пойму чего вы хотите и зачем. – EvgeniyZ Aug 11 '21 at 18:31
  • если вы хотите сделать цикл параллельным, используйте Task.Parallel, в противном случае не вижу альтернативы потокам – return Aug 11 '21 at 18:46
  • 3
    Task.Run, т.к. он съедает N потоков Task.Run использует шедулер по умолчанию, а значит используется пул потоков, который ограничен. То есть потоков будет столько, сколько решит пул потоков, а он для этого и создан, чтобы такие вещи решать. – tym32167 Aug 11 '21 at 18:48
  • можно так var models = items.SelectMany(i=>i.CommunityIds).AsParallel().Seelct(x=>ToContentItem(x,...)).ToList(); - по умолчанию тут потоков будет создано столько же, как и в вшем варианте. Но это можно ограничить настроками параллелизма, читайте про PLinq – tym32167 Aug 11 '21 at 18:50
  • 1
    }); - вот тут ; лишняя – CrazyElf Aug 11 '21 at 18:58
  • ToContentItem - что делает этот метода, какова его реализация? Он загружает процессор или обращается к IO? – Alexander Petrov Aug 11 '21 at 19:12
  • Аналогичные вопросы к методам TryGetValueOrDefault. / Если методы загружают процессор - то без потоков не обойтись. Если методы используют ввод-вывод - их следует переписать с использованием асинхронности. – Alexander Petrov Aug 11 '21 at 19:13
  • 1
    Не используйте конструктор new Task, совсем, никогда, вообще. – aepot Aug 11 '21 at 20:01

0 Answers0