I'm using TPL in my current project and using Parallel.Foreach to spin many threads. The Task class contains Wait() to wait till the task gets completed. Like that, how I can wait for the Parallel.ForEach to complete and then go into executing next statements?
5 Answers
You don't have to do anything special, Parallel.Foreach()
will wait until all its branched tasks are complete. From the calling thread you can treat it as a single synchronous statement and for instance wrap it inside a try/catch.
Update:
The old Parallel class methods are not a good fit for async (Task based) programming. But starting with dotnet 6 we can use Parallel.ForEachAsync()
await Parallel.ForEachAsync(items, (item, cancellationToken) =>
{
await ...
});
There are a few overloads available and the 'body' method should return a ValueTask.

- 263,252
- 30
- 330
- 514
-
16"Parallel.Foreach() will wait until all its branched tasks are complete" it can be confused in some situation, like (async task inside): Parallel.ForEach(groupedUnreadMessages, async unreadMsgCollection => { /*works*/}); – Bo HU Jul 27 '16 at 10:41
-
here is an other issues in stackoverflow : http://stackoverflow.com/questions/11564506/nesting-await-in-parallell-foreach – Bo HU Jul 27 '16 at 10:47
-
5This answer is from 2011, before async/await. But like I said, spawning threads inside the ForEach isn't a good idea. Neither is an async Action. The links you posted provides good info and solutions. – H H Jul 27 '16 at 11:23
-
2"spawning threads inside the ForEach isn't a good idea" can you expand? Is that "unless you make sure you await before returning"? – Gianthra Jun 28 '18 at 09:11
You don't need that with Parallel.Foreach: it only executes the foreach in as many thread as there are processors available, but it returns synchronously.
More information can be found here

- 16,268
- 4
- 64
- 88
As everyone here said - you dont need to wait for it. What I can add from my experience: If you have an async body to execute and you await some async calls inside, it just ran through my code and did not wait for anything. So I just replaced the await with .Result - then it worked as intended. I couldnt find out though why is that so :/

- 127
- 1
- 3
-
it's better not to use async methods as sync when you can do the first mode. in `Parallel.Foreach` we better use the `await ...` instead of `.Result` on them. – MRebati Sep 01 '20 at 13:06
-
@MRebati I tried first the await in there, but the code execution ran nonetheless through without awaiting... Thats why I tried .Result and it worked somehow. But whatever, maybe I did something else wrong – Oleg Boguslawski Sep 02 '20 at 18:13
-
1It worked for me after this change, refer similar and few other solutions here: https://stackoverflow.com/a/40893434/12193988 – Maulik Nov 16 '21 at 04:58
if you are storing results from the tasks in a List, make sure to use a thread-safe data structure such as ConcurrentBag, otherwise, some results would be missing because of concurrent write issues.

- 1,141
- 14
- 24
I believe that you can use IsCompleted like follows:
if(Parallel.ForEach(files, f => ProcessFiles(f)).IsCompleted)
{
// DO STUFF
}

- 27
- 6