Task.Run
для выполнения связанных с ЦП синхронных операций в потоке пула потоков.Поскольку эта операция, которую вы выполняете, уже асинхронна, поэтому использование Task.Run
означает, что вы планируете работу для выполнения в потоке пула потоков, и эта работа просто запускает асинхронную операцию, которая затемзавершается почти сразу и выполняет любую асинхронную работу без блокировки потока пула потоков.Таким образом, с помощью Task.Run
вы ожидаете, чтобы запланировать работу в пуле потоков, но на самом деле не выполняете значимой работы.Вам лучше просто запустить асинхронную операцию в текущем потоке.
Единственное исключение было бы, если бы DoAsyncJob
были реализованы неправильно и по какой-то причине не были фактически асинхронными, вопреки его имени и подписи, и фактически выполнили много синхронной работы перед возвратом.Но если он делает это, вы должны просто исправить этот ошибочный метод, а не использовать Task.Run
для его вызова.
На заметку о том, что нет никакой причины иметь ConcurrentDictionary
для сбора результатов здесь,Task.WhenAll
возвращает коллекцию результатов всех выполненных вами задач.Просто используйте это.Теперь вам даже не нужен метод, чтобы обернуть ваш асинхронный метод и обработать результат каким-либо особым образом, дополнительно упрощая код:
var tasks = Enumerable.Range(0, 100).Select(DoAsyncJob);
var results = await Task.WhenAll(tasks);
Console.WriteLine($"Items in results {results.Count}");