Andrey Shchekin
Andrey Shchekin

Reputation: 21599

What actually happens when using foreach/WhenAll?

From the threading point of view, what happens in this code?

public static Task ForEach<T>(IEnumerable<T> items, Func<T, Task> process) {
    var tasks = new List<Task>();
    foreach (var item in items) {
        tasks.Add(process(item));
    }
    return Task.WhenAll(tasks);
}

Are all tasks scheduled to run in parallel or can some execute sequentially?
Would there be problems (aside from memory usage) if the collection is large?

Upvotes: 2

Views: 61

Answers (1)

Thomas Levesque
Thomas Levesque

Reputation: 292445

Are all tasks scheduled to run in parallel or can some execute sequentially?
Would there be problems (aside from memory usage) if the collection is large?

There is no way to answer that question in general, because it depends on the kind of Task that is returned by process. A Task is not a thread; it's just something that represents an operation with a mechanism to be notified when the operation completes. Some tasks are implemented using threads (e.g. when you use Task.Run or Task.Factory.StartNew), but others are not (e.g. tasks created with TaskCompletionSource<T>).

Now, assuming that in your case, process returns tasks that run in a thread. Again, it depends how the task was scheduled. Typically, if you use Task.Run, or Task.Factory.StartNew with the default creation options, it will use a thread from the ThreadPool. So if you create more tasks than the maximum number of threads in the pool, they will be queued until threads become available.

So, several tasks will run in parallel, but not all of them; it depends on the maximum number of threads in the ThreadPool.

Upvotes: 5

Related Questions