Вот псевдокод, который я запускаю:
Вариант № 1:
List<Task> tasks = new List<Task>();
foreach (...)
{
Task task = Task.Run(() =>
{
doWork();
});
tasks.Add(task);
}
Task.WhenAll(tasks.AsParallel()).ContinueWith((t) =>
{
// process results/handle errors
...
});
Вариант № 2:
List<Task> tasks = new List<Task>();
foreach (...)
{
Task task = Task.Run(() =>
{
doWork();
});
tasks.Add(task);
}
Task.WhenAll(tasks.AsParallel()).Wait();
// process results/handle errors
...
Мой вопрос такой,почему способ doWork
вызывается радикально отличается между # 1 и # 2?Это из-за замысла, и я просто не понимаю, как это должно работать?
Мое (очевидно, ошибочное) понимание / предположение состояло в том, что doWork
будет вызываться в многопоточном / асинхронном режиме, параллельно-if-доступно, в обоих сценариях, единственное отличие состоит в том, что вызывающий код будет ожидать завершения по-разному.Но то, как задачи на самом деле выполняются , будет одинаковым, потому что они запланированы / «запущены» одинаково.
Но из того, что я могу сказать после отладки обеих версий кода,вариант # 1 приводит к тому, что doWork
вызывается в истинно параллельном / полностью многопоточном режиме, тогда как вариант # 2, кажется, действует как однопотоковое, последовательное выполнение каждой задачи.
Что яотсутствует